为了账号安全,请及时绑定邮箱和手机立即绑定

为什么不允许将接口{}转换为 cgo 类型?

为什么不允许将接口{}转换为 cgo 类型?

Go
绝地无双 2022-09-19 10:45:11
这更像是一个技术问题,而不是一个真正的问题。由于我们在 cgo 中没有可变参数函数,并且目前没有有效的解决方案,我想知道是否有可能将接口{} 转换为 cgo 类型。因此,这将使我们能够拥有更多的动态函数。我很确定我们甚至不允许以动态方式为导出(//export)函数中的参数分配类型,也不允许使用省略号。那么,所有这些限制背后的原因是什么呢?感谢您的回答。import "C"//export Foofunc Foo(arg1, arg2, arg3) {    }
查看完整描述

1 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

C 编译器允许(但不是必需的)使用不同的返回机制返回不同的类型。例如,某些 C 编译器可能会在寄存器中返回结果,在寄存器中返回结果,在寄存器中返回整数结果,在寄存器中返回指针结果。float%f0double%f0:f1%d0%a0

对于为 Go 编写 Cgo 接口的人来说,这意味着他们必须以不同的方式处理每种 C 函数。换句话说,不可能写:

generic_type Cfunc(ctype1 arg1, ctype2 arg2) { ... }

我们必须知道,在编译时,返回浮点数/双精度型<某种整数类型>/<某种指针类型>以便我们可以获取正确的寄存器并将其(或它们的)值填充到 Cgo 返回值槽中,Cgo 接口可以在其中获取它并包装起来以便在 Go 中使用。Cfunc

作为实现 Cgo 包装器以调用 C 函数的 Go 编译器的用户,这对您来说意味着您必须知道正确的类型。没有一般的答案;没有办法在这里使用。您必须将精确、正确的类型传达给 Cgo 层,以便 Cgo 层可以使用该精确、正确的类型信息在编译时生成正确的机器代码。interface{}

如果 C 编译器编写者有某种方式标记其代码,例如,在链接时,链接器可以拉入正确的“将正确的寄存器保存到内存”位置,这将使 Cgo 包装器作者能够使用链接器在链接时自动查找 C 函数的类型。但是这些C编译器没有为链接器提供这种能力。

您的特定编译器是其中之一吗?我们不知道:你没有说。但:

我很确定我们甚至不允许以动态方式为导出(//export)函数中的参数分配类型,也不允许使用省略号。那么,所有这些限制背后的原因是什么呢?

这是正确的,上面的(略带理论性的)例子就是一个原因。(我通过混合来自68k C编译器和SPARC C编译器的实际技术来构造此示例,因此我认为没有任何单独的C编译器。但是过去确实存在这样的例子,SPARC 系统仍然返回 %o0 的整数,或者在 V8 SPARC 上返回 %o0+%o1 的整数,而不是以 %f0 或 %f0+%f1 为单位的浮点数。


查看完整回答
反对 回复 2022-09-19
  • 1 回答
  • 0 关注
  • 59 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信