Accessing Go compiled applications through FFI
I finally started to create some useful Go code and, just like some previous posts(in pt-BR, ) where I integrated python, lua and C, I would love to use them with old python code instead of C/C++. For that, I had to generate a shared library. The process is easy as expected, requiring only the import of library “C” and a comment before function definition, exporting the function name, as following examples.
package main import "C" //export ModXY func ModXY(x int) int { return x * 2 } func main() {}
Now, let’s compile it to generate a shared lib:
$ go build -o libmod.so -buildmode=c-shared
This results on two files, libmod.so and libmod.h where the first one is a shared library itself and the second one is the headers to include Go types into a C application. More on this soon. First let’s check libmod.so
$ file libmod.so libmod.so: Mach-O 64-bit dynamically linked shared library x86_64
Nice, as expected on OSX. Now let’s try to import it with python ctypes!
Python 2.7.12 (default, Sep 28 2016, 18:41:32) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import ctypes >>> lib = ctypes.CDLL('libmod.so') >>> lib.ModXY(13,2) 1
It worked like a charm! It is, actually, pretty easy to deal with. Now let’s find out the raison d’etre of this .h file. If, for some crazy reason, you need to embbed Go code inside a C file, simply include the .h and use the functions normally, as the following example:
#include <stdio.h> #include "libmod.h" int main(void){ printf("the rest of division of 13 per 2 is %d", (int)ModXY(13,2)); return 0; }
then, compile it with:
$ gcc -o purexecutable testlib.c libmod.so
and
$ file purexecutable purexecutable: Mach-O 64-bit executable x86_64 $ ./purexecutable the rest of division of 13 per 2 is 1
Yey! Again, simple and efficient. The design documentation of this feature may be found here( http://golang.org/s/execmodes ). That’s all