Skip to content

Instantly share code, notes, and snippets.

@kingluo
Created July 8, 2015 08:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kingluo/a91e4fe2751b82a96a55 to your computer and use it in GitHub Desktop.
Save kingluo/a91e4fe2751b82a96a55 to your computer and use it in GitHub Desktop.
cgo good example
#include "c.h"
#include "_cgo_export.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct A* echo(void) {
const char* p = "hello world";
GoString p2;
p2.p = (char*)p;
p2.n = strlen(p);
struct MyFunction_return v = MyFunction(1, 2, p2);
printf("%ld %s\n", v.r0, v.r1);
struct A* a = malloc(sizeof(*a));
strcpy(a->val, "foobar");
a->tag = 92;
return a;
}
package c
// #include "c.h"
// #include <stdlib.h>
import "C"
import "fmt"
import "unsafe"
//export MyFunction
func MyFunction(arg1, arg2 int, arg3 string) (v int64, p *C.char) {
v = int64(arg1 + arg2)
v += int64(len(arg3))
s := make([]byte, 256)
copy(s, "str from MyFunction")
p = (*C.char)(unsafe.Pointer(&s[0]))
return
}
func TestC() {
aPtr := C.echo()
fmt.Println(C.GoString(&aPtr.val[0]), aPtr.tag)
C.free(unsafe.Pointer(aPtr))
}
#ifndef _CCCCCC_
#define _CCCCCC_
struct A {
char val[512];
int tag;
};
extern struct A* echo(void);
#endif
package main
import "c"
func main() {
c.TestC()
}
No Makefile!
king@debian:~/go/src/c$ tree $GOPATH/src/c*
/home/king/go/src/c
|-- c.c
|-- c.go
`-- c.h
/home/king/go/src/ctest
`-- ctest.go
0 directories, 4 files
king@debian:~/go/src/c$ cd -
/home/king/go/src/ctest
king@debian:~/go/src/ctest$ go run ctest.go
14 str from MyFunction
foobar 92
@kingluo
Copy link
Author

kingluo commented Jul 8, 2015

由于GO的运行必须是可执行程序,所以GO必须是主体,所以C回调GO仅限于必须使用回调的场合。
这里主要关注C和GO边界的两个方向上的数据传递效率。
从GO到C,任何GO type都不能传入,包括字符串,这意味着不可重用任何GO type数据,只能拷贝出来赋值给对应的C type来传递,效率受限,但是有一个例外,就是可以cast [] byte进去,这意味着如果有一些大内存操作的边界传入,例如视频缓冲,那么还是可以重用同一块内存而变得高效的。
从C到GO,就灵活多了,任何指针都可以直接访问,这意味着不需要任何数据拷贝。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment