Skip to content

Instantly share code, notes, and snippets.

@geraldstanje

geraldstanje/README.md

Last active Oct 14, 2020
Embed
What would you like to do?
Call go from C++ using a shared library

https://medium.com/@walkert/fun-building-shared-libraries-in-go-639500a6a669

https://www.darkcoding.net/software/building-shared-libraries-in-go-part-2/

https://karthikkaranth.me/blog/calling-c-code-from-go/

https://www.cockroachlabs.com/blog/the-cost-and-complexity-of-cgo/

https://golang.org/cmd/cgo/#hdr-Passing_pointers

https://blog.filippo.io/building-python-modules-with-go-1-5/

Build modes The 'go build' and 'go install' commands take a -buildmode argument which indicates which kind of object file is to be built. Currently supported values are:

-buildmode=archive Build the listed non-main packages into .a files. Packages named main are ignored.

-buildmode=c-archive Build the listed main package, plus all packages it imports, into a C archive file. The only callable symbols will be those functions exported using a cgo //export comment. Requires exactly one main package to be listed.

-buildmode=c-shared Build the listed main package, plus all packages it imports, into a C shared library. The only callable symbols will be those functions exported using a cgo //export comment. Requires exactly one main package to be listed.

-buildmode=default Listed main packages are built into executables and listed non-main packages are built into .a files (the default behavior).

-buildmode=shared Combine all the listed non-main packages into a single shared library that will be used when building with the -linkshared option. Packages named main are ignored.

-buildmode=exe Build the listed main packages and everything they import into executables. Packages not named main are ignored.

-buildmode=pie Build the listed main packages and everything they import into position independent executables (PIE). Packages not named main are ignored.

-buildmode=plugin Build the listed main packages, plus all packages that they import, into a Go plugin. Packages not named main are ignored. On AIX, when linking a C program that uses a Go archiv

package main
import "C"
import (
"sort"
)
//export Add
func Add(a, b int) int {
return a + b
}
//export Sub
func Sub(a, b int) int {
return a - b
}
//export Print
func Print(str string) {
fmt.Printf("Go prints: %s\n", str)
}
func strFxn(input string) string {
return "Hello " + input + " World"
}
//export StrFxn
func StrFxn(cinput *C.char) *C.char {
// C data needs to be manually managed in memory.
// But we will do it from C++.
input := C.GoString(cinput)
return C.CString(strFxn(input))
}
//export Sort
func Sort(vals []int) {
sort.Ints(vals)
}
func main() {
// We need the main function to make possible
// CGO compiler to compile the package as C shared library
}
#include <iostream>
#include <string>
#include "bidder_module.h"
int main() {
int res = Add(1, 2);
std::cout << res << std::endl;
GoString str;
str.p = "Hello World";
str.n = strlen(str.p);
Print(str);
std::string s = "Bidder";
char *cstr = new char[s.length()+1];
std::strcpy (cstr, s.c_str());
cstr = StrFxn(cstr);
std::cout << cstr << std::endl;
delete[] cstr;
return 0;
}
# if you are on osx:
# this creates bidder_module.h and bidder_module.dylib file
go build -o bidder_module.dylib -buildmode=c-shared bidder_module.go
g++ main.cpp bidder_module.dylib -o main && ./main
# if you are on linux:
# this creates bidder_module.h and bidder_module.so file
# go build -o bidder_module.so -buildmode=c-shared bidder_module.go
# g++ main.cpp bidder_module.so -o main && ./main
@hexvalid

This comment has been minimized.

Copy link

@hexvalid hexvalid commented Sep 24, 2020

Nice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.