2017-02-15 127 views
0

我一直在使用cgo来连接Go和C.但是,当试图对Go和C++执行相同操作时,每次尝试调用函数时都会收到编译错误。从代码的目录使用go build .,我得到以下错误:Go无法调用C++函数

./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 documentation,支持C++。我为Linux/amd64使用Go版本1.7.5。

非常感谢!

回答

0

我可能是错的,但我认为cgo只支持C++,因为它知道如何在看起来像包含C++源代码的非Go文件上调用C++编译器,就这些了。

问题是,C++编译器使用所谓的"mangling"作为从编译文件导出的符号。导出符号最初是 ,仅适用于C语言,其中所有可以导出的都是普通的函数和变量,但C++增加了类和函数重载,并且从编译(“对象”)文件中导出这些符号, C++编译器 需要使用某些模式对它们进行“破坏”,以编码类名称 以及这些名称中的参数类型。更糟糕的是,每个C++编译器 品牌都使用自己的mangling架构。

所以我觉得虽然cgo能够编译C++代码,它像是假定 所有符号出口(被转到被使用),在C++文件 包裹在extern "C" { ... }(见this)。

如果你需要调用“本地”C++导出的东西,你需要使用 SWIG我认为。

+0

哦,这很有道理!非常感谢你的帮助! –