cgo
2022-02-09 本文已影响0人
hehehehe
https://github.com/chai2010/gopherchina2018-cgo-talk
go->c
package main
/*
#include <stdio.h>
static void SayHello(const char* s) {
puts(s);
}
*/
import "C"
func main() {
C.SayHello(C.CString("Hello, World\n"))
C.puts(C.CString("你好!\n"))
}
编译参数
- CFLAGS 只包含纯 C 代码(*.c)
- CPPFLAGS 包含 C/C++ 代码(.c,.cc,.cpp,.cxx)
- CXXFLAGS 只包含纯 C++ 代码(.cc,.cpp,*.cxx)
链接参数
- LDFLAGS
package main
//使用#cgo定义库路径
/*
#cgo CFLAGS: -I .
#cgo LDFLAGS: -L . -lhello
#include "hello.h"
*/
import "C"
func main() {
C.hello()
}
--------------------------------------------------
gcc -c hello.c
ar -cru libhello.a hello.o
--------------------------------------------------
#ifndef HELLO_H
#define HELLO_H
void hello(void);
#endif
--------------------------------------------------
#include <stdio.h>
void hello()
{
printf("hello world\n");
}
c->go
package main
// extern void SayHello(char* s);
import "C"
import "fmt"
func main() {
C.SayHello(C.CString("Hello, World\n"))
}
//export SayHello
func SayHello(s *C.char) {
fmt.Print(C.GoString(s))
}
ctypes
生成纯C接口的动态库
// main.go
package main
import "C"
import "fmt"
func main() {}
//export SayHello
func SayHello(name *C.char) {
fmt.Printf("hello %s!\n", C.GoString(name))
}
--------------------------------------------------
go build -buildmode=c-shared -o say-hello.so main.go
--------------------------------------------------
# hello.py
import ctypes
libso = ctypes.CDLL("./say-hello.so")
SayHello = libso.SayHello
SayHello.argtypes = [ctypes.c_char_p]
SayHello.restype = None
SayHello(ctypes.c_char_p(b"hello"))
基于Py扩展接口(有问题)
//涉及内存的部分必须在C语言定义
//模块的名字是 gopkg
/*
static PyObject* cgo_PyInit_gopkg(void) {
static PyMethodDef methods[] = {
{"sum", Py_gopkg_sum, METH_VARARGS, "Add two numbers."},
{NULL, NULL, 0, NULL},
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT, "gopkg", NULL, -1, methods,
};
return PyModule_Create(&module);
}
*/
import "C"
//export PyInit_gopkg
func PyInit_gopkg() *C.PyObject {
return C.cgo_PyInit_gopkg()
}
//export Py_gopkg_sum
func Py_gopkg_sum(self, args *C.PyObject) *C.PyObject {
var a, b C.int
if C.cgo_PyArg_ParseTuple_ii(args, &a, &b) == 0 {
return nil
}
return C.PyLong_FromLong(C.long(a + b))
}
$ go build -buildmode=c-shared -o gopkg.so main.go