对于我正在做的与现有库集成的工作,我最终需要编写一些额外的 C 代码来提供可通过 CGo 使用的接口。
为了避免冗余数据副本,我希望能够将一些标准 Go 类型(例如 Go 字符串)传递给这些 C 适配器函数。
我可以看到 CGo 生成的头文件中定义了一些类型GoString
,GoInterface
供导出的 Go 函数使用,但是有什么方法可以在 CGo 识别的我自己的函数原型中使用这些类型?
目前,我最终void *
在 C 原型中使用并unsafe.Pointer(&value)
在 Go 端传递。这不像我想要的那样干净(一方面,它使 C 代码能够写入值)。
更新:
为了清楚起见,我确实知道 Go 的原生字符串类型和 C 之间的区别char *
。我的观点是,因为无论如何我都会复制传递给我的 C 函数的字符串数据,所以让 Go 端的代码自己复制是没有意义的。
我也知道字符串布局在 Go 的未来版本中可能会发生变化,并且它的大小可能因平台而异。但是 CGo 已经通过_cgo_export.h
它为我生成的文档标头向我公开了与当前平台匹配的类型定义,因此谈论它未指定似乎有点奇怪:
typedef struct { char *p; int n; } GoString;
但是似乎没有办法在 CGo 可见的原型中使用这个定义。我并不太担心二进制兼容性,因为使用这个定义的代码将是我的 Go 包的一部分,所以源代码级别的兼容性就足够了(如果那样的话,更新包也没什么大不了的情况并非如此)。