linux Debian Buster
go version go1.11.6 linux/amd64
gcc version 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
with change: 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
2
Answers
is probably wrong. Read the invoking GCC chapter of the GCC documentation. Order of arguments to
g++
matters a lot.Also, test(1) could be some existing executable. I recommend to use some other name.
So consider compiling with
You probably want debugging information (
-g
), warnings (-Wall
) and some optimization (-O
)You did comment
This is curious. I assume your operating system is some Linux. Then, can’t you just use inter-process communication facilities between a process running a Go program and another process running your C++ program? Consider perhaps using JSONRPC or HTTP between them. There exist several open source libraries in Go and in C++ to help you.
PS. As I commented, calling C++ code from a Go program could be much simpler. Of course you do need to read the Go documentation and the blog about
cgo
and probably the C++ dlopen minihowto and some C++ reference.You have to use
GoString
rather thanstd::string
in the C++ version. The error message you are getting is because of the type mismatch, manifesting as a link-time error.See the cgo reference.
Here’s a working example. There’s a few differences from yours. The
//export
directive is needed to include the function in the generated header file, the argument is*C.char
rather thanstring
orGoString
. The C++ code uses the header generated by cgo, and there has to be a const-removing cast from the static string (because go doesn’t have C-like const).libmylib.go
main.cpp
commands
This compiles to go file, generating
libmylib.so
andlibmylib.h
in the current directory.The compiles the C++ program, linking it to the shared library above:
To run the program,
LD_LIBRARY_PATH
needs to be set to the current directory. That would be different if program was installed and the shared library put in a sensible place.