Reputation: 14583
I'm playing around with automatically generating some C code, compiling it to a shared library and loading it with ctypes, and I'm curious if anyone can enlighten me as to what might be required to use parts of the Python API from within such a library (without creating a full-fledged module)
For example, I have some quick code hacked together:
PyObject* test() {
PyObject* to_ret = NULL;
PyGILState_STATE gstate = PyGILState_Ensure();
to_ret = Py_BuildValue("i", 1+2);
PyGILState_Release(gstate);
return to_ret;
}
Which I compile to a .so and load with ctypes.
However, when I run the above I get:
>>> ctypes.CDLL("test.so").test()
138145104
So I'm clearly doing something wrong. Any thoughts/tips would be welcome.
SOLUTION: Aha, the above does work but ctypes by default expects an int return type and so is casting the PyObject* to an integer. It seems there's no way to return an arbitary python object using ctypes, so generating a full module would seem to be the way to go.
Upvotes: 1
Views: 357
Reputation: 177755
It seems it can be done in Python 2.7, which supports a ctypes.py_object
as a type. I built a library from your example code and used the following:
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> t = CDLL('test').test
>>> t.restype = py_object
>>> t()
3
Upvotes: 3