加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

我可以通过CGo定义接受原生Go类型的C函数吗?

发布时间:2020-12-16 07:04:29 所属栏目:百科 来源:网络整理
导读:对于我正在进行的与现有库集成的工作,我最终需要编写一些额外的C代码来提供可通过CGo使用的接口. 为了避免冗余数据副本,我希望能够将一些标准Go类型(例如Go字符串)传递给这些C适配器函数. 我可以看到在CGo生成的头文件中定义了GoString和GoInterface类型以供
对于我正在进行的与现有库集成的工作,我最终需要编写一些额外的C代码来提供可通过CGo使用的接口.

为了避免冗余数据副本,我希望能够将一些标准Go类型(例如Go字符串)传递给这些C适配器函数.

我可以看到在CGo生成的头文件中定义了GoString和GoInterface类型以供导出的Go函数使用,但有没有办法在我自己的函数原型中使用这些类型,CGo会识别?

目前,我最终在C原型中使用void *并在Go端传递unsafe.Pointer(& value).这不像我想的那么干净(一方面,它赋予C代码写入值的能力).

更新:

为了清楚起见,我确实知道Go的本地字符串类型和C char *之间的区别.我的观点是,因为我将复制传递给我的C函数的字符串数据,所以让Go端的代码自己制作副本是没有意义的.

我也明白,字符串布局可能会在Go的未来版本中发生变化,其大小可能因平台而异.但CGo已经通过它为我生成的文档_cgo_export.h标题公开了与当前平台匹配的类型定义,所以谈论它未指定似乎有点奇怪:

typedef struct { char *p; int n; } GoString;

但似乎没有办法在CGo可见的原型中使用这个定义.我并不过分担心二进制兼容性,因为使用此定义的代码将成为我的Go包的一部分,因此源级兼容性就足够了(如果更新包,那就不是那么重要了.事实并非如此).

解决方法

并不是的.您无法安全地混合,例如Go字符串(字符串)和C“字符串”(* char)代码,而不使用提供的帮助程序,即. GoString和CString.原因是为了符合语言规范,必须在Go和C世界之间创建字符串内容的完整副本.不仅如此,垃圾收集器必须知道要考虑什么(Go字符串)和忽略什么(C字符串).还有更多的事情要做,但让我在这里保持简单.

类似和/或其他限制/问题适用于其他Go“魔法”类型,例如map或interface {}类型.在接口类型的情况下(但不仅仅是它),重要的是要意识到接口{}的内部实现(不仅仅是这种类型)没有被指定并且是特定于实现的.

这不仅仅是关于gc和gccgo之间可能存在的差异.这也意味着您的代码将在编译器开发人员决定更改(未指定且因此无保证)实现的某些细节时随时中断.

另外,即使Go(现在)没有使用压缩垃圾收集器,它可能会改变,没有一些固定机制,任何直接访问Go运行时东西的代码将再次注定失败.

结论:仅将简单实体作为C函数的参数传递.具有简单字段的POD结构也是安全的(指针字段通常不是).从复杂的Go类型中,使用为Go字符串提供的帮助程序,它们存在(非常好)的原因.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读