Skip to content

Instantly share code, notes, and snippets.

@autozimu
Last active August 29, 2015 14:04
Show Gist options
  • Save autozimu/6d921ac315d43b66bc6b to your computer and use it in GitHub Desktop.
Save autozimu/6d921ac315d43b66bc6b to your computer and use it in GitHub Desktop.
Compile C to shared library and load it using ffi
#!/usr/bin/env python
"""
Quickly open an dylib connection. Helpful for testing and exploring.
"""
import os, sys
import glob2
# recursive glob, which is builtin function in python3
import subprocess
from cffi import FFI
def ffilib(libname):
"""
open FFI object with dylib
"""
headers = glob2.glob('**' + libname + '.h*')
sources = glob2.glob('**' + libname + '.c*')
if len(headers) != 1:
print 'ERROR: could not find header for ' + libname
sys.exit(1)
if len(headers) != 1:
print 'ERROR: could not find source for ' + libname
sys.exit(1)
header = headers[0]
source = sources[0]
ffi = FFI()
ffi.cdef(subprocess.Popen(['cc', '-E', header],
stdout=subprocess.PIPE).communicate()[0])
# dirty hack, ffi.verify() report error on osx
# try compile dylib every time before open it
dylib = libname + '.dylib'
subprocess.call(['cc', '-dynamiclib', '-o', dylib, source])
return ffi, ffi.dlopen(dylib)
def test_ffilib():
ffi, lib = ffilib('hello')
assert lib.num_int == 7
assert lib.num_double == 0
assert list(lib.array) == [1, 2, 3]
assert lib.chr == "a"
assert ffi.string(lib.string) == "CIVIC"
assert lib.nul == ffi.NULL
#include <stdio.h>
#include "hello.h"
int num_int = 7;
double num_double = 0;
int array[3] = {1, 2, 3};
char chr = 'a';
char string[] = "CIVIC";
int *nul = NULL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment