Quick Bytes - Running C++ in Go
How to run C++ code in Go using swig
Background
At work, I was tasked to integrate a C++ library into a Go project. The library was written in C++ and I had to evaluate some viable options. Of course, I could rewrite the library in Go, but that would be a lot of work. I could also use cgo, but I wanted to keep the Go code clean and separate from the C++ code. I decided to use SWIG.
Introduction
What is SWIG?
SWIG stands for Simplified Wrapper and Interface Generator. It is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is used with different types of languages including common scripting languages such as Perl, PHP, Python, Ruby, and PHP.
How does SWIG work?
SWIG reads the header files of the C/C++ code and generates wrapper code that can be compiled and linked with the Go code. The wrapper code is a Go package that can be imported and used in the Go code.
Installation
In MacOS, you can install SWIG using Homebrew:
1
brew install swig
In Ubuntu/Debian based systems, you can install SWIG using apt:
1
2
sudo apt-get update
sudo apt-get install swig
For other operating systems, you can download the SWIG binaries from the official website.
Usage
Using SWIG in other languages is more complicated than using it in Go. In other languages, you need to write an interface file that tells SWIG directives on how to generate the wrapper code.
In Go, fortunately, there is native support for SWIG. We can create a .swigcxx
file that contains the directives and the Go compiler will automatically generate the wrapper code behind the scenes and it will work seamlessly.
However, only caveat is that the code is generated in the Go complier’s working directory which means code linting and formatting tools might not work as expected.
Example
A sample project can be found here. It follows the video project structure albeit with a classic factorial function.
Steps
- Write the C++ code
- Write the SWIG interface file (
.swigcxx
) - Write the package file that imports “C” which has the same name as the module name in the
.swigcxx
file - Create a
main.go
file that imports the package and uses the C++ functions. Note that linting and formatting tools might not work as expected because the generated code is in the Go compiler’s working directory. - Run
go run main.go