Cgo找不到<iostream>之类的标准库

I'm trying to include C++ code in my Go code, but isn't recognized.

I first thought that it considers it as C code and try (and fail) to compile as such, but removing the include line actually gives me c++ error troubleshooting like this error: ‘cout’ is not a member of ‘std’ The code compiles correctly with g++.

I have tried to add the -lstdc++ LDLFLAG, and add the path to the lib in CXXFLAG but it doesn't change a thing.

I have made some other tests (and all fail) but this is the smallest one.

This is the c++ files

test.cpp

#include "test.hpp"
    int test() 
    {
        std::cout << "Hello, World! ";
        return 0;
    }

test.hpp 
#include <iostream>
int test() ;

And this is my go file

//#cgo CXXFLAGS: -I/usr/lib/
//#cgo LDFLAGS: -L/usr/lib/ -lstdc++
//#include "test.hpp"
import "C"

func main() {
    C.test()
}

I compile using go build but I have also tried to use env CGO_ENABLED CGO_CXXFLAGS="-std=c++11" go build (the env part is fish specific) and it returns the same error.

It's supposed to compile correctly, but instead I have iostream: No such file or directory.

EDIT : I tried to add CFLAGS: -x c++ as suggested in the comments, the compiler searches at the right place, but I get another error invalid conversion from ‘void*’ to ‘_cgo_96e70225d9dd_Cfunc_test(void*)::<unnamed struct>*’ [-fpermissive] and I don't know if it's related to this new flafg

douba2705
douba2705 现在,<iostream>问题已解决,但是我不确定无效的转换是否与给定的解决方案有关。是的,我已经在声明周围应用了extern“C”,但是它不会将内容更改为无效的强制转换错误
大约一年之前 回复
dsvjw20866
dsvjw20866 那么,现在的确切错误是什么?关于无效转换或丢失<iostream>的那个?如果是前者,您是否按照我的第一条评论中的建议对函数应用了适当的外部链接规则?
大约一年之前 回复
duanluangua8850
duanluangua8850 谢谢,使用-v选项现在更加清晰了,是的,它可以“按原样”编译,我说过它可以使用g++正确编译。
大约一年之前 回复
drsc10888
drsc10888 谢谢,我试过了,它正确地调用了cc1plus而不是cc1,但现在又有另一个错误,它在我编辑的答案中
大约一年之前 回复
doqw89029
doqw89029 附带说明:如果要从Go调用C++代码的函数,则必须将它们的声明放在extern“C”{...}块中以禁止名称修饰,这将使导出的函数不可用于与Go代码。(更多信息在这里)。
大约一年之前 回复
dtwncxs3547
dtwncxs3547 尝试在CXXFLAGS(或任何适合您的编译器)中添加--verbose,然后传递-x命令行选项以进行构建(或进行安装-无论使用何种方式)。然后查看C++编译器写出的有关其如何处理其输入文件的内容。(嗯,这是一个愚蠢但必不可少的问题:C++代码是否可以“按原样”编译?我的意思是直接表示,而不是通过go工具链编译。)
大约一年之前 回复
dplsnw7329
dplsnw7329 使用#cgoCFLAGS:-xc++和#cgoLDFLAGS:-lstdc++
大约一年之前 回复
drxyaox153896
drxyaox153896 其实您是对的,它与C代码没有任何关系,我更正了这个问题,非常感谢
大约一年之前 回复
dsj2014
dsj2014 您还应该显示如何触发此过程,即使用什么命令。
大约一年之前 回复
duanmi4379
duanmi4379 这不是我尝试编译的唯一代码,并且不理解c++语法,我将编辑问题
大约一年之前 回复
dongze8698
dongze8698 我看不到有证据表明它正在“尝试将其编译为C代码”,只是它找不到标准库头文件之一。
大约一年之前 回复

2个回答

cgo makes it very easy to wrap C with Go, but C++ is a bit different. You have to extern "C" the functions that you want to make a function-name in C++ have 'C' linkage, otherwise the linker won't see the function. So, the actual problem is in the C++ header file. If you can't change the C++ code because it's a library, you may have to write wrappers (example).

This will compile:

.
├── test.cpp
├── test.go
└── test.hpp

test.hpp

#ifdef __cplusplus
extern "C" {
#endif

    int test();
#ifdef __cplusplus
}
#endif

test.cpp

#include <iostream>
#include "test.hpp"
int test() {
    std::cout << "Hello, World! ";
    return 0;
}

test.go

package main

// #cgo CXXFLAGS: -I/usr/lib/
// #cgo LDFLAGS: -L/usr/lib/ -lstdc++
// #include "test.hpp"
import "C"

func main() {
    C.test()
}

Put the files in the same folder, run go build

Hello, World!

douyunhuan9886
douyunhuan9886 我认同。 这可能就是人们最终写包装纸的原因。
大约一年之前 回复
doutui6241
doutui6241 所以说我在hpp中有c ++特定的代码,我将无法使其工作,对吗? 因为那是我一开始的问题
大约一年之前 回复
duanjia1870
duanjia1870 我不确定。 可能是因为我们将其导入到test.go文件中,并且只需要类似C的代码
大约一年之前 回复
doutong2132
doutong2132 我现在知道了,但是当我将其放回hpp时,为什么它会给我与以前相同的错误(iostream:没有这样的文件或目录)? (即使我将其放在外部“ C”中)
大约一年之前 回复
doupinwan0563
doupinwan0563 我相信在C ++中,大多数人都将标头中所需的include以及在那里仅cpp文件中所需的所有内容都放在了其中
大约一年之前 回复
doudi4137
doudi4137 谢谢您的回答,终于可以了。 但是,为什么将#include <iostream>放在.cpp中而不是.hpp中?
大约一年之前 回复

我现在也碰到了类似的情况:

我现在在使用 cgo 调用 几个so,但是这几个so的头文件中 引入了 vector 等C++标准库数据结构;
正常编译时,提示错误: error: vector: No such file or directory

查了一些资料,尝试了 #cgo amd64 386 CFLAGS: -DX86=1 -xc++ 参数,结果编译的时候不报找不到文件错误了

但是报如下错误:(如下错误是我调用了共享库中的一个接口报的错):
unexpected type: (unsupported type ReferenceType)

    var nPDLLHandle C.int32_t
    ret := int32(C.DPSDK_Create(C.DPSDK_CORE_SDK_SERVER, &nPDLLHandle))   //这一行报错:unexpected type: (unsupported type ReferenceType),调用肯定是正确的。

cgo 调用 C++ 的共享库,有什么解决办法吗? 必须把C++包装成C才能用吗?

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐