├── README.md ├── c++ ├── SConstruct ├── c++_interface_lib │ ├── interface.cc │ └── interface.h └── c++_static_lib │ ├── work.cc │ └── work.h └── go └── src ├── cgo_lib └── cgo_lib.go └── go_prog └── go_prog.go /README.md: -------------------------------------------------------------------------------- 1 | # Go-Cpp # 2 | 3 | This project demonstrates how to call C++ code from Go program without 4 | the need of using SWIG. 5 | 6 | The basic idea is to write a 7 | [C wrapper](https://github.com/wangkuiyi/go-cpp/tree/master/c%2B%2B/c%2B%2B_interface_lib) 8 | of 9 | [C++ code](https://github.com/wangkuiyi/go-cpp/tree/master/c%2B%2B/c%2B%2B_static_lib), 10 | and use `cgo` to call this C wrapper. 11 | 12 | ## Checkout and Build 13 | 14 | git clone -b develop https://github.com/wangkuiyi/go-cpp 15 | cd go-cpp/c++ 16 | scons 17 | cd ../go 18 | export GOPATH=`pwd` 19 | cd src/go_prog 20 | go install 21 | DYLD_LIBRARY_PATH=$GOPATH/../c++/ $GOPATH/bin/go_prog 22 | 23 | Note that you need to install SCons to build the C++ part. In order 24 | to install SCons on Mac OS X, you can use Homebrew. 25 | 26 | If you are using Linux, the last command to run the demo program is: 27 | 28 | LD_LIBRARY_PATH=$GOPATH/../c++/ $GOPATH/bin/go_prog 29 | -------------------------------------------------------------------------------- /c++/SConstruct: -------------------------------------------------------------------------------- 1 | StaticLibrary('cppstaticlib', ['c++_static_lib/work.cc']) 2 | SharedLibrary('cppinterfacelib', ['c++_interface_lib/interface.cc'], LIBS=['cppstaticlib'], LIBPATH='.') 3 | -------------------------------------------------------------------------------- /c++/c++_interface_lib/interface.cc: -------------------------------------------------------------------------------- 1 | #include "../c++_static_lib/work.h" 2 | // Thie file, as a C++ source file, should not include C interfacing 3 | // header files, i.e., "interface.h". 4 | 5 | extern "C" { 6 | long CRandom() { 7 | // As the rng is seeded in every call, it is not random at all. 8 | RandomNumberGenerator r(1); 9 | return r.Rand(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /c++/c++_interface_lib/interface.h: -------------------------------------------------------------------------------- 1 | #ifndef GO_CPP_CPP_CPP_STATIC_LIB_INTERFACE_H_ 2 | #define GO_CPP_CPP_CPP_STATIC_LIB_INTERFACE_H_ 3 | 4 | // This file is to be used by the cgo library, so it should export 5 | // only C stuff. 6 | long CRandom(); 7 | // but not any C++ things, for example, CppRandom(). 8 | 9 | #endif // GO_CPP_CPP_CPP_STATIC_LIB_INTERFACE_H_ 10 | -------------------------------------------------------------------------------- /c++/c++_static_lib/work.cc: -------------------------------------------------------------------------------- 1 | #include "work.h" 2 | 3 | long CppRandom() { 4 | RandomNumberGenerator r(1); 5 | return r.Rand(); 6 | } 7 | -------------------------------------------------------------------------------- /c++/c++_static_lib/work.h: -------------------------------------------------------------------------------- 1 | #ifndef GO_CPP_CPP_CPP_STATIC_LIB_WORK_H_ 2 | #define GO_CPP_CPP_CPP_STATIC_LIB_WORK_H_ 3 | 4 | #include 5 | 6 | class RandomNumberGenerator { 7 | public: 8 | RandomNumberGenerator(unsigned int seed) { 9 | // A real random number generator should not delegates the work to 10 | // srandom/random. 11 | srandom(seed); 12 | } 13 | 14 | long Rand() { 15 | return random(); 16 | } 17 | }; 18 | 19 | #endif // GO_CPP_CPP_CPP_STATIC_LIB_WORK_H_ 20 | -------------------------------------------------------------------------------- /go/src/cgo_lib/cgo_lib.go: -------------------------------------------------------------------------------- 1 | package cgo_lib 2 | 3 | // #cgo CFLAGS: -I../../../c++/ 4 | // #cgo LDFLAGS: -L../../../c++ -lcppinterfacelib 5 | // #include "c++_interface_lib/interface.h" 6 | import "C" 7 | 8 | func GoRandom() int { 9 | return int(C.CRandom()) 10 | } 11 | -------------------------------------------------------------------------------- /go/src/go_prog/go_prog.go: -------------------------------------------------------------------------------- 1 | // If it complains cannot find the shared library when you run this 2 | // program, please export DYLD_LIBRARY_PATH= if you use OS 3 | // X, or export LD_LIBRARY_PATH= if you use Linux. 4 | package main 5 | 6 | import ( 7 | "cgo_lib" 8 | "fmt" 9 | ) 10 | 11 | func main() { 12 | fmt.Println(cgo_lib.GoRandom()) 13 | } 14 | --------------------------------------------------------------------------------