cgo

作者: hehehehe | 来源:发表于2022-02-09 17:47 被阅读0次

    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
    

    相关文章

      网友评论

          本文标题:cgo

          本文链接:https://www.haomeiwen.com/subject/retgkrtx.html