linux Debian Buster
go版本go1.11.6 linux/am64
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
main.cpp
#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我的测试程序
/usr/bin/ld:/tmp/ccu4fXFB.o:在函数'main'中:main.cpp:(.text+0x53(:对"say(std::__cxx11::basic_string<char,std::char_traits,std:;allocater>("的未定义引用
collect2:错误:ld返回1个退出状态
更改:package main -> package mylib
CGO_ENABLED=1 go build-o libmylib.so-buildmode=c-shared libmylib.go
-buildmode=c-shared只需要一个主包
您必须在C++版本中使用GoString
而不是std::string
。您收到的错误消息是因为类型不匹配,表现为链接时间错误。
请参阅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() {}
main.cpp
#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
g++ -L/path/to/lib/ -lmylib main.cpp -o test
可能是错误的。阅读GCC文档的调用GCC章节g++
的参数顺序非常重要。
此外,测试(1(可以是一些现有的可执行文件。我建议用其他名字。
因此,考虑使用进行编译
g++ -Wall -g -O main.cpp -L/path/to/lib/ -lmylib -o my-test-program
您可能需要调试信息(-g
(、警告(-Wall
(和一些优化(-O
(
你确实评论了
我需要在C++项目中使用Go文件中的一些函数。
这很奇怪。我认为您的操作系统是Linux。那么,你就不能在运行Go程序的进程和运行C++程序的另一个进程之间使用进程间通信设施吗?考虑在它们之间使用JSONRPC或HTTP。Go和C++中有几个开源库可以帮助您。
PS。正如我所评论的,从Go程序中调用C++代码可能会简单得多。当然,您确实需要阅读Go文档和关于cgo
的博客,可能还需要阅读C++dlopen minihowto和一些C++参考资料。