Skip to content

Instantly share code, notes, and snippets.

@tonyseek
Last active November 5, 2022 15:20
Show Gist options
  • Save tonyseek/7821993 to your computer and use it in GitHub Desktop.
Save tonyseek/7821993 to your computer and use it in GitHub Desktop.
Build Python binding of C++ library with cffi (PyPy/Py3K compatible)

Run with Python:

pip-2.7 install cffi
PYTHON=python2.7 sh go.sh

Run with PyPy:

pip-pypy install cffi
PYTHON=pypy sh go.sh

Run with Py3K:

pip-3.3 install cffi
PYTHON=python3.3 sh go.sh

The expected output:

=> now run the native one
hello, world
=> now run the pypy bound one
hello, cffi
#!/usr/bin/env sh
set -e
[ -z "$PYTHON" ] && PYTHON="python"
g++ -o ./hello ./libhello.cpp
echo "=> now run the native one"
./hello
g++ -o ./libhello.so ./libhello.cpp -fPIC -shared
echo "=> now run the $PYTHON bound one"
python hello.py
import cffi
ffi = cffi.FFI()
ffi.cdef("void cffi_hello(char *name);")
C = ffi.dlopen("./libhello.so")
def hello(name):
C.cffi_hello(name)
if __name__ == "__main__":
hello("cffi")
#include <iostream>
class User
{
std::string name;
public:
User(char *name):name(name) {}
User(std::string &name):name(name) {}
std::string greet() { return "hello, " + name; }
};
void hello(char *name)
{
User user(name);
std::cout << user.greet() << std::endl;
}
int main()
{
hello((char *) "world");
return 0;
}
extern "C"
{
extern void cffi_hello(char *name)
{
return hello(name);
}
}
@0xnurl
Copy link

0xnurl commented Mar 2, 2017

This is extremely helpful. Thanks!

@jakab922
Copy link

Thanks! Really useful indeed.

@yunqu
Copy link

yunqu commented Oct 26, 2018

Like it

@danielmdPhantom
Copy link

very helpful. thanks!

@ayushmankumar7
Copy link

Traceback (most recent call last):
File "hello.py", line 12, in
hello("cffi")
File "hello.py", line 8, in hello
C.cffi_hello(name)
TypeError: initializer for ctype 'char *' must be a bytes or list or tuple, not str

I am getting this error.... can't find why

@ayushmankumar7
Copy link

Just found a solution to use hello("cffi".encode("ascii"))

@tonyseek
Copy link
Author

Just found a solution to use hello("cffi".encode("ascii"))

You are right. The str and bytes are significantly different things in Python 3.

This works too:

hello(b"explicit bytes")

@cdbdev
Copy link

cdbdev commented Nov 5, 2022

Thanks, this is nice. Could you also post an example for Windows with MSVC? Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment