Go 无法调用 C++ 函数。

huangapple go评论79阅读模式
英文:

Go can't call c++ function

问题

我一直在使用cgo来在Go和C之间进行接口调用。然而,当我尝试在Go和C++之间做同样的事情时,每次尝试调用函数时都会出现编译错误。在代码目录中使用go build .命令时,我得到了以下错误信息:

./main.go: In function 'void _cgo_3612c872201c_Cfunc_getint(void*)':
./main.go:48:53: error: invalid conversion from 'void*' to '_cgo_3612c872201c_Cfunc_getint(void*)::<anonymous struct>*' [-fpermissive]
./main.go:54:4: error: invalid conversion from 'void*' to '_cgo_3612c872201c_Cfunc_getint(void*)::<anonymous struct>*' [-fpermissive]

我在下面放了一个非常简单的示例,展示了这个问题。

main.go:

package main

/*
#cgo CFLAGS: -x c++

int getint()
{
    return 1;
}
*/
import "C"

import (
    "fmt"
)

func main() {
    fmt.Println(C.getint())
}

有人知道这是否是cgo的一个bug,还是我编写代码的问题吗?根据cgo文档,支持C++。我正在使用Go版本1.7.5,操作系统是linux/amd64。

非常感谢!

英文:

I have been using cgo to interface between Go and C. However, when trying to do the same for Go and C++, I get a compile error every time I attempt to call a function. Using go build . from the code's directory, I get the following errors:

./main.go: In function &#39;void _cgo_3612c872201c_Cfunc_getint(void*)&#39;:
./main.go:48:53: error: invalid conversion from &#39;void*&#39; to &#39;_cgo_3612c872201c_Cfunc_getint(void*)::&lt;anonymous struct&gt;*&#39; [-fpermissive]
./main.go:54:4: error: invalid conversion from &#39;void*&#39; to &#39;_cgo_3612c872201c_Cfunc_getint(void*)::&lt;anonymous struct&gt;*&#39; [-fpermissive]

I've put a super simple example below which shows the problem.

main.go:

package main

/*
#cgo CFLAGS: -x c++

int getint()
{
    return 1;
}
*/
import &quot;C&quot;

import (
    &quot;fmt&quot;
)

func main() {
    fmt.Println(C.getint())
}

Does anyone know if this is a bug in cgo, or something wrong with how I wrote the code? According to the cgo documentation, C++ is supported. I'm using Go version 1.7.5 for linux/amd64.

Thanks so much!

答案1

得分: 3

我可能错了,但我认为cgo只在某种程度上支持C++,它知道如何在非Go文件上调用C++编译器,这些文件看起来像包含C++源代码,仅此而已。

问题在于C++编译器对从编译文件中导出的符号使用所谓的“名称修饰”(mangling)。导出符号最初只用于类似C的语言,其中可以导出的只有普通函数和变量,但C++添加了类和函数重载,并且为了从编译(“对象”)文件中导出这些符号,C++编译器需要使用特定的模式对类的名称和参数类型进行编码。更糟糕的是,每个C++编译器品牌都使用自己的名称修饰模式。

因此,我认为虽然cgo能够编译C++代码,但它假设您的C++文件中导出的所有符号(供Go使用)都包装在extern "C" { ... }中(参见这里)。

如果您需要调用“本地”的C++导出内容,您需要使用SWIG

英文:

I may be wrong, but I think cgo supports C++ only in the sense it knows how to invoke a C++ compiler on the non-Go files which looks like containing C++ source code, and that's all.

The problem is that C++ compilers use so-called "mangling" for the symbols made exported from the compiled files. Exporting symbols were originally
intended only for C-like languages, where all which can be exported are plain
functions and variables, but C++ adds classes and function overloading,
and to export such symbols from compiled ("object") files, a C++ compiler
needs to "mangle" them using certain schema to encode names of classes
and types of arguments in these names. What's worse, each C++ compiler
brand uses its own mangling schemas.

So I think while cgo is able to compile C++ code, it sort of assumes that
all the symbols exported (to be used by Go) in your C++ files are
wrapped in extern &quot;C&quot; { ... } (see this).

If you need calls to "native" C++ exported stuff, you'd need to use
SWIG I reckon.

huangapple
  • 本文由 发表于 2017年2月16日 01:59:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/42256833.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定