Reputation: 9592
I am using Python CFFI and want to open a library where I can call free
on some data I get back. In Linux and Mac, I put free
in the cdefs and load a base C library with dlopen(None)
.
from cffi import FFI
header = """
typedef struct {
int32_t* members;
} container_t;
void free(void *ptr);
"""
cdefs = FFI()
cdefs.cdef(header)
cdefs.set_source("_main", "") # So that the header can be `include`d externally
lib = cdefs.dlopen(None)
def free_members(container) -> None:
lib.free(container.members)
This fails on Windows with the well-documented error:
OSError: dlopen(None) cannot work on Windows for Python 3 (see http://bugs.python.org/issue23606)
What gives the equivalent behavior on Windows? I just want free
, which should be available on any old DLL anywhere.
Upvotes: 2
Views: 234
Reputation: 12990
Try to use the API approach with ffi_builder.compile()
. This lets you write portable C code like
ffi_builder.cdef(""" void free(void *); """)
ffi_builder.set_source("_main", "")
ffi_builder.compile()
and then you can use
from _main import lib, ffi
lib.free(p)
Trying to get the correct free()
function is a complete mess on Windows, because it is not standard. There are a number of libraries (and multiple versions of them) that each provide malloc()
and free()
, and of course if you mix the malloc()
from one library with the free()
from another, then everything explodes. The solution I describe above should work if compile()
happens to use the same compiler (and version!) as the one that was used to make your library. In general, that's why it's a poor design on Windows to say "this function returns a pointer and you have to call free()
yourself".
Upvotes: 5