c++ - 在 C++ 中使用 Go
问题描述
linux Debian 克星
去版本 go1.11.6 linux/amd64
gcc 版本 8.3.0 (Debian 8.3.0-6)
libmylib.go
package main
import "C"
import (
"fmt"
)
func say(text string) {
fmt.Println(text)
}
func main(){}
mylib.h
#ifndef MY_LIB_H
#define MY_LIB_H
#include <string>
void say(std::string text);
#endif
主文件
#include <string>
#include "mylib.h"
using namespace std;
int main() {
string text = "Hello, world!";
say(text);
return 0;
}
CGO_ENABLED=1 go build -o libmylib.so -buildmode=c-shared libmylib.go
g++ -L/path/to/lib/ -lmylib main.cpp -o my-test-program
/usr/bin/ld: /tmp/ccu4fXFB.o: 在函数'main'中: main.cpp:(.text+0x53): undefined reference to `say(std::__cxx11::basic_string<char, std:: char_traits, std::allocator >)'
collect2: 错误: ld 返回 1 退出状态
有变化:package main -> package mylib
CGO_ENABLED=1 go build -o libmylib.so -buildmode=c-shared libmylib.go
-buildmode=c-shared 只需要一个主包
解决方案
您必须使用GoString
而不是std::string
在 C++ 版本中。您收到的错误消息是由于类型不匹配,表现为链接时错误。
请参阅cgo 参考。
这是一个工作示例。和你的有一些不同。该//export
指令需要在生成的头文件中包含函数,参数是*C.char
而不是string
或GoString
。C++ 代码使用由 cgo 生成的标头,并且必须从静态字符串中进行 const 移除强制转换(因为 go 没有类似 C 的 const)。
libmylib.go
package main
import "C"
import (
"fmt"
)
//export say
func say(text *C.char) {
fmt.Println(C.GoString(text))
}
func main() {}
主文件
#include "libmylib.h"
int main(void) {
say(const_cast<char*>("hello world"));
return 0;
}
命令
这编译为 go 文件,生成libmylib.so
并libmylib.h
在当前目录中。
go build -o libmylib.so -buildmode=c-shared libmylib.go
编译 C++ 程序,将其链接到上面的共享库:
g++ -L. main.cpp -lmylib -o hello_program
要运行程序,LD_LIBRARY_PATH
需要设置到当前目录。如果安装了程序并将共享库放在合理的位置,那将是不同的。
LD_LIBRARY_PATH=. ./hello_program
推荐阅读
- r - R:计算两个最大值之间有多少个值
- angular - Angular:链式双向属性绑定
- r - 具有某些操作的数据框中的唯一计数和总计数
- python - Python函数作用域的一些疑惑
- node.js - 未定义所需模块时,Sinon 单元测试失败
- python-3.x - 运行时烧瓶:应用程序未从谷歌云平台的 SSH 终端在浏览器中打开
- flutter - 在 Flutter 中使用 Google Maps 和 Container 堆叠 Widget
- unity3d - 禁用环境光 (HDRP)
- animation - Flutter:多个动画 onTapDown
- windows - exec.command 不在 Windows 上执行(golang)