Sunday, October 27, 2013

How to Call C++ from Go

.
└── src
    └── cgotest
        ├── hello
        │   ├── cpp
        │   │   └── hellocpp.cpp
        │   ├── hello.go
        │   ├── include
        │   │   └── hellocpp.h
        │   └── lib
        │       └── libhellocpp.so
        └── main.go
hellocpp.h
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef _HELLOCPP_H_
#define _HELLOCPP_H_
 
#ifdef __cplusplus
extern "C" {
#endif
    void SayHello();
#ifdef __cplusplus
}
#endif
 
#endif
hellocpp.cpp
1
2
3
4
5
6
7
#include <iostream>
#include "hellocpp.h"
using namespace std;
 
void SayHello() {
    cout << "Hello from C++" << endl;
}
Let's now create a C++ shared library.
cd $GOPATH/src/cgotest/hello
mkdir lib
g++ -Wall -shared -fpic cpp/hellocpp.cpp -Iinclude -o lib/hellocpp.so
hello.go
1
2
3
4
5
6
7
8
9
10
package hello
 
// #cgo CFLAGS: -Iinclude
// #cgo LDFLAGS: -Llib -lhellocpp
// #include "hellocpp.h"
import "C"
 
func HelloFromCpp() {
    C.SayHello()
}
main.go
1
2
3
4
5
6
7
package main
 
import "cgotest/hello"
 
func main() {
    hello.HelloFromCpp()
}
There seems to be a bug that makes setting relative paths in LDFLAGS not to work. The workaround is to set LIBRARY_PATH env variable using absolute path.
cd $GOPATH
export LIBRARY_PATH=$GOPATH/src/cgotest/hello/lib
export LD_LIBRARY_PATH=$LIBRARY_PATH
go build cgotest
./cgotest
Output:
Hello from C++

No comments:

Post a Comment