Экспорт Go-функций в C
Экспорт Go-функций в C с помощью cgo позволяет вызывать код,
написанный на Go, из программ на C. Для этого используется
директива //export, которая делает Go-функцию доступной
для C-кода. В качестве параметров функция может принимать
стандартные типы C (C.int, C.char* и другие),
а возвращать - соответствующие значения.
Синтаксис
//export FunctionName
func FunctionName(param1 C.int, param2 *C.char) C.int {
// тело функции
}
Пример
Давайте создадим простую Go-функцию, которая принимает два целых числа и возвращает их сумму:
package main
/*
#include <stdio.h>
*/
import "C"
import "fmt"
//export Sum
func Sum(a C.int, b C.int) C.int {
res := a + b
fmt.Printf("Sum of %d and %d is %d\n", a, b, res)
return res
}
func main() {
// функция main необходима для компиляции,
// но она не используется при экспорте
}
Теперь эту функцию можно вызвать из C-программы:
#include <stdio.h>
extern int Sum(int a, int b);
int main() {
int result = Sum(5, 7);
printf("Result from Go: %d\n", result);
return 0;
}
Результат выполнения C-программы:
"Sum of 5 and 7 is 12"
"Result from Go: 12"
Пример
Рассмотрим более сложный пример, где Go-функция принимает C-строку и возвращает новую C-строку:
package main
/*
#include <stdlib.h>
*/
import "C"
import "strings"
import "unsafe"
//export ToUpper
func ToUpper(str *C.char) *C.char {
goStr := C.GoString(str)
upperStr := strings.ToUpper(goStr)
return C.CString(upperStr)
}
//export FreeString
func FreeString(str *C.char) {
C.free(unsafe.Pointer(str))
}
func main() {}
C-программа, использующая эту функцию:
#include <stdio.h>
#include <stdlib.h>
extern char* ToUpper(char* str);
extern void FreeString(char* str);
int main() {
char* input = "hello world";
char* result = ToUpper(input);
printf("Original: %s\n", input);
printf("Upper: %s\n", result);
FreeString(result);
return 0;
}
Результат выполнения C-программы:
"Original: hello world"
"Upper: HELLO WORLD"
Пример
Экспортированная функция может возвращать структуры. Рассмотрим пример с экспортом функции, возвращающей структуру C:
package main
/*
typedef struct {
int x;
int y;
} Point;
*/
import "C"
//export CreatePoint
func CreatePoint(x C.int, y C.int) C.Point {
return C.Point{x: x, y: y}
}
//export SumPoint
func SumPoint(p C.Point) C.int {
return p.x + p.y
}
func main() {}
C-программа, использующая эти функции:
#include <stdio.h>
typedef struct {
int x;
int y;
} Point;
extern Point CreatePoint(int x, int y);
extern int SumPoint(Point p);
int main() {
Point p = CreatePoint(10, 20);
int sum = SumPoint(p);
printf("Point: (%d, %d)\n", p.x, p.y);
printf("Sum: %d\n", sum);
return 0;
}
Результат выполнения C-программы:
"Point: (10, 20)"
"Sum: 30"
Смотрите также
-
директиву
//export,
которая делает Go-функцию доступной для C -
функцию
C.CString,
которая преобразует Go-строку в C-строку -
функцию
C.GoString,
которая преобразует C-строку в Go-строку -
функцию
C.free,
которая освобождает память, выделенную в C