go - 为什么不允许将 interface{} 转换为 cgo 类型?
问题描述
这更像是一个技术问题,而不是真正的问题。由于我们在 cgo 中没有可变参数函数并且目前没有有效的解决方案,我想知道是否可以将 interface{} 转换为 cgo 类型。所以这将使我们有更多的动态功能。我很确定我们甚至不允许以动态方式为导出(//export)函数中的参数分配类型,也不允许使用省略号。那么所有这些限制背后的原因是什么?
谢谢回答。
import "C"
//export Foo
func Foo(arg1, arg2, arg3) {
}
解决方案
允许但不要求 C 编译器使用不同的返回机制返回不同的类型。例如,一些 C 编译器可能会在寄存器中返回float
结果,在寄存器对中返回结果,在寄存器中返回整数结果,在寄存器中返回指针结果。%f0
double
%f0:f1
%d0
%a0
对于为 Go 编写 Cgo 接口的人来说,这意味着他们通常必须以不同的方式处理这些 C 函数中的每一种。换句话说,不可能这样写:
generic_type Cfunc(ctype1 arg1, ctype2 arg2) { ... }
我们必须知道,在编译时,它Cfunc
返回 float/double/<some-integer-type>/<some-pointer-type> 以便我们可以获取正确的寄存器并填充其(或它们的)值) 进入 Cgo 返回值槽,Cgo 接口可以在其中获取并包装它以供 Go 使用。
这对您来说意味着什么,作为实现 Cgo 包装器以调用 C 函数的 Go 编译器的用户,您必须知道正确的类型。没有普遍的答案;这里没有办法使用interface{}
。您必须将准确、正确的类型传达给 Cgo 层,以便 Cgo 层可以使用该准确、正确的类型信息在编译时生成正确的机器代码。
如果 C 编译器编写者有某种方式标记他们的代码,例如,在链接时,链接器可以拉入正确的“将正确的寄存器保存到内存”位置,这将使 Cgo 包装器作者能够使用链接器自动在链接时找到 C 函数的类型。但是这些 C 编译器不向链接器提供这种能力。
您的特定编译器是其中之一吗?我们不知道:你没有说。但:
我很确定我们甚至不允许以动态方式为导出(//export)函数中的参数分配类型,也不允许使用省略号。那么所有这些限制背后的原因是什么?
这是正确的,上面的(略带理论性的)示例是一个原因。(我通过混合来自 68k C 编译器和 SPARC C 编译器的实际技术构建了这个示例,所以我认为没有像这样的单个 C 编译器。但是这样的示例在过去确实存在,并且 SPARC 系统仍然以 % 为单位返回整数V8 SPARC 上的 o0 或 %o0+%o1,而 %f0 或 %f0+%f1 中的浮点数。)
推荐阅读
- c# - UWP - 未调用来自 DataGrid 的命令
- chatbot - 将 BERT 合并到 RASA 管道中的问题
- java - 在 Java 中读取 .tsv 文件
- python - 如何对 Keras 文本分类进行预测?
- scala - hasDefiniteSize 和 knownSize
- node.js - 如何找出在 ember fastboot 中运行应用程序时发生错误的原因
- mysql - MySql 选择日期相差 30 分钟的最后一行
- r - 为什么 sf::st_transform 在应用于具有 sf 列(POINT)的 df 时返回空几何?
- ios - 在使用 React Native 的 IOS 运行时出现“未处理的 JS 异常:本机模块不能为空”错误
- java - 仅当资源在 Spring Security 中得到保护时,如何检查访问令牌?