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"))
}

编译参数

链接参数

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
上一篇下一篇

猜你喜欢

热点阅读