重庆网站建设外包哪家好,重庆市建设安全管理网,商城网站制作报价,wordpress 展开折叠cgo 从 C 传递 slice 到 go这里一般会用在c的callback中。需要加一个wrapper#xff0c;比直接调用go函数中间多了一个转换步骤#xff0c;但方便了许多。执行流程为#xff0c;c调用发起 - c wrapper - go export.go://export a_function_callbackfunc a_function_…cgo 从 C 传递 slice 到 go这里一般会用在c的callback中。需要加一个wrapper比直接调用go函数中间多了一个转换步骤但方便了许多。执行流程为c调用发起 - c wrapper - go export.go://export a_function_callbackfunc a_function_callback(args []C.astruct) {}.c:extern void a_function_callback(GoSlice args);void a_function_callback_c(args *C.astruct) {GoSlice args_go;args_go.data args;args_go.len nargs;args_go.cap nargs;return a_function_callback(args_go);}这里的GoSlice需要从 export 出来的 .h 中获取或者 include 该 .h文件。也可以直接拷贝过来注意不要产生类型冲突。#ifndef GO_CGO_PROLOGUE_H#define GO_CGO_PROLOGUE_Htypedef long long GoInt64;typedef GoInt64 GoInt;typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;#endifC.CString 的自动化回收方法一般使用 C.CString 时定义一个临时变量存储结果使用 defer C.free 回收这个临时的变量。在 go 的 runtime 包中有一个SetFinalizer方法可以在回收对象的时候调用一个处理函数。那么我们可以考虑使用它来自动化回收 C.CString产生的临时变量。type CString struct {Ptr *C.char}func CCString(s string) *CString {p : C.CString(s)this : CString{Ptr: p}runtime.SetFinalizer(this, freeCString)return this}func freeCString(cs *CString) {C.free(unsafe.Pointer(cs.Ptr))}在使用的时候基本能嵌入到调用的位置不需要显式定义一个临时变量并执行 defer C.free。C.somefunc(CCString(s).Ptr)注意只在somefunc不接管传递的参数的所有权时调用这种方式如果somefunc接管了所有权而在未来某时间内存被回收了则会出现程序SEGFAULT崩溃。这种可能会产生一点runtime效率损失另外还有额外的内存分配看情况使用。bool 类型的转换处理在 C 语言中c99之前 bool 都是定义为 int的要想转换为go的bool类型比较曲折。var bval_c C.GBooleanvar bval_go boolif int(bval) 1 {bval_go true} else {bval_go false}如果go有三元运算符的话也可一行代码实现该转换问题是go没有三元运算符。一般来说对其包装一个简单的转换函数比较好比如 c2gobool(C.GBoolean).有时候不同的 C 项目中 bool 定义不同所以一般需要为每个项目定义这么一个函数而不能放在一个库中共用。在 c99 之后则没有这个问题cgo能够直接判断是内置的bool类型能够直接转换为go的bool。var bval_c C._Boolvar bval_go bool(bval_c)