-
-
Save kingluo/a91e4fe2751b82a96a55 to your computer and use it in GitHub Desktop.
cgo good example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _CCCCCC_ | |
#define _CCCCCC_ | |
struct A { | |
char val[512]; | |
int tag; | |
}; | |
extern struct A* echo(void); | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "c" | |
func main() { | |
c.TestC() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
由于GO的运行必须是可执行程序,所以GO必须是主体,所以C回调GO仅限于必须使用回调的场合。
这里主要关注C和GO边界的两个方向上的数据传递效率。
从GO到C,任何GO type都不能传入,包括字符串,这意味着不可重用任何GO type数据,只能拷贝出来赋值给对应的C type来传递,效率受限,但是有一个例外,就是可以cast [] byte进去,这意味着如果有一些大内存操作的边界传入,例如视频缓冲,那么还是可以重用同一块内存而变得高效的。
从C到GO,就灵活多了,任何指针都可以直接访问,这意味着不需要任何数据拷贝。