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
#ifndef _HELLOCPP_H_
#define _HELLOCPP_H_

#ifdef __cplusplus
extern "C" {
#endif
    void SayHello();
#ifdef __cplusplus
}
#endif

#endif
hellocpp.cpp
#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
package hello

// #cgo CFLAGS: -Iinclude
// #cgo LDFLAGS: -Llib -lhellocpp
// #include "hellocpp.h"
import "C"

func HelloFromCpp() {
    C.SayHello()
}
main.go
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