我正在将我用 C 编写的一些服务器代码移植到 Go 中,它使用了一个我真的不想重写的加密库。相反,我正在尝试使用 Cgo 编写一个包装器,以便我的其余代码可以更轻松地调用它。这是 lib 标头的一部分:
// encryption/encryption.h
#define CRYPT_BBCFG 1
typedef struct {
// ...bunch of fields...
uint32_t bb_posn;
} CRYPT_SETUP;
int CRYPT_CreateKeys(CRYPT_SETUP* cs, void* key, unsigned char type);
这是我试图开始工作的概念验证片段:
package goserv
//#include "encryption/encryption.h"
import "C"
func main() {
cdata := new(C.struct_CRYPT_SETUP)
key := make([]byte, 48)
C.CRYPT_CreateKeys(cdata, &key, C.CRYPT_BLUEBURST)
}
我在标题中定义了一个测试函数 ( int test() { return 1; }
),从我的代码 (via) 调用它也没有问题,C.test()
也没有引用任何 #defined'd 常量 ( C.CRYPT_BBCFG
),但是当我尝试运行go install goserv时出现以下错误:
Undefined symbols for architecture x86_64:
"_CRYPT_CreateKeys", referenced from:
__cgo_e89359206bf1_Cfunc_CRYPT_CreateKeys in goserv.cgo2.o
(maybe you meant: __cgo_e89359206bf1_Cfunc_CRYPT_CreateKeys)
ld: symbol(s) not found for architecture x86_64
在这一点上,我假设我只是没有使用正确的参数调用函数。我的印象是 cdata 是 type *C.struct_CRYPT_SETUP
, key 应该是*byte
(尽管没有 & 也不能工作)和 C.CRYPT_BLUEBURST 类型......东西。尝试C.uchar(CRYPT_BLURBURST)
也不会改变任何事情。
关于编译这段代码有什么建议吗?
编辑:忘记我的平台,我正在运行 Mac OS X 10.10
Edit2(已解决):Jsor 关于使用 unsafe.Pointer 和 key 的第一个元素的地址的观点有所帮助,但我还必须将我的 C 源文件移动到与我的 Go 文件相同的目录中。使用 C.struct_CRYPT_DATA 而不是 C.CRYPT_DATA 会导致另一种类型错误,所以如果其他人遇到这样的错误:
./goserv.go:18: cannot use cdata (type *C.struct_CRYPT_SETUP) as type *C.struct___0 in argument to _Cfunc_CRYPT_CreateKeys
然后删除 struct_ 前缀(尽管 cgo 文档说这是直接引用 C 结构类型的方法)