在 C++ 中使用 Go
Using Go in C++
linux Debian 克星
go版本go1.11.6linux/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
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 my-test-program
/usr/bin/ld: /tmp/ccu4fXFB.o: in function 'main':
main.cpp:(.text+0x53): undefined reference to `say(std::__cxx11::basic_string<char, std::char_traits, std::allocator >)'
collect2: error: ld returned 1 exit status
有变化:package main -> package mylib
CGO_ENABLED=1 go build -o libmylib.so -buildmode=c-shared libmylib.go
-buildmode=c-shared requires exactly one main package
g++ -L/path/to/lib/ -lmylib main.cpp -o test
可能是错误的。阅读invoking GCC chapter of the GCC documentation。 g++
的参数顺序很重要。
此外,test(1) 可能是一些 现有的 可执行文件。我建议使用其他名称。
所以考虑用
编译
g++ -Wall -g -O main.cpp -L/path/to/lib/ -lmylib -o my-test-program
您可能需要调试信息 (-g
)、警告 (-Wall
) 和一些优化 (-O
)
你评论了
I need to use some functions from a Go file in my C ++ project.
这很好奇。我假设您的操作系统是 Linux。那么,你不能只在它们之间使用 inter-process communication facilities between a process running a Go program and another process running your C++ program? Consider perhaps using JSONRPC or HTTP 吗? Go 和 C++ 中有几个开源库可以帮助您。
PS。正如我评论的那样,从 Go 程序调用 C++ 代码可能要简单得多。当然你需要阅读 Go documentation and the blog about cgo
and probably the C++ dlopen minihowto and some C++ reference.
您必须在 C++ 版本中使用 GoString
而不是 std::string
。您收到的错误消息是由于类型不匹配,表现为 link-time 错误。
这是一个工作示例。和你的有一些不同。需要 //export
指令将函数包含在生成的 header 文件中,参数是 *C.char
而不是 string
或 GoString
。 C++ 代码使用由 cgo 生成的 header,并且必须从静态字符串中转换为 const-removing(因为 go 没有 C-like 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
linux Debian 克星
go版本go1.11.6linux/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
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 my-test-program
/usr/bin/ld: /tmp/ccu4fXFB.o: in function 'main': main.cpp:(.text+0x53): undefined reference to `say(std::__cxx11::basic_string<char, std::char_traits, std::allocator >)'
collect2: error: ld returned 1 exit status
有变化:package main -> package mylib
CGO_ENABLED=1 go build -o libmylib.so -buildmode=c-shared libmylib.go
-buildmode=c-shared requires exactly one main package
g++ -L/path/to/lib/ -lmylib main.cpp -o test
可能是错误的。阅读invoking GCC chapter of the GCC documentation。 g++
的参数顺序很重要。
此外,test(1) 可能是一些 现有的 可执行文件。我建议使用其他名称。
所以考虑用
编译g++ -Wall -g -O main.cpp -L/path/to/lib/ -lmylib -o my-test-program
您可能需要调试信息 (-g
)、警告 (-Wall
) 和一些优化 (-O
)
你评论了
I need to use some functions from a Go file in my C ++ project.
这很好奇。我假设您的操作系统是 Linux。那么,你不能只在它们之间使用 inter-process communication facilities between a process running a Go program and another process running your C++ program? Consider perhaps using JSONRPC or HTTP 吗? Go 和 C++ 中有几个开源库可以帮助您。
PS。正如我评论的那样,从 Go 程序调用 C++ 代码可能要简单得多。当然你需要阅读 Go documentation and the blog about cgo
and probably the C++ dlopen minihowto and some C++ reference.
您必须在 C++ 版本中使用 GoString
而不是 std::string
。您收到的错误消息是由于类型不匹配,表现为 link-time 错误。
这是一个工作示例。和你的有一些不同。需要 //export
指令将函数包含在生成的 header 文件中,参数是 *C.char
而不是 string
或 GoString
。 C++ 代码使用由 cgo 生成的 header,并且必须从静态字符串中转换为 const-removing(因为 go 没有 C-like 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