I used SWIG
to connect my C++
program with Python
. From cFunctions.py
I call C
function named checkVal
like following:
lib = cdll.LoadLibrary('./test.so')
xml_bytesTrx = bytearray(b'<xml>...</xml>')
a1 = (ctypes.c_byte*513)(*xml_bytesTrx)
class EFT_TRX(Structure):
_fields_ = [
("a2",c_ulong),
("a3",c_char*16),
("a4",c_char*4),
("a5",c_ushort),
("a6",c_char*41),
("a7",c_char*13),
("a8",c_char*21),
("a1",c_byte*513)
]
Trx = EFT_TRX(0,"0",'CHF',0,'4506445638161117',"123456123456","202020",
a1)
def check(arg1, arg2):
eftTransactionRes = lib.checkVal(arg1,arg2,Trx.a4,Trx.a5,
Trx.a6,Trx.a7,Trx.a8,
Trx.a1)
Trx.a3 = arg2
return eftTransactionRes
And in C header file (test.h
) is defined like following:
long TEST_API checkVal(
_IN____ const unsigned long a2,
_INOUT_ char a3[16],
_IN____ const char a4[4],
_IN____ const unsigned short a5,
_IN____ const char a6[41],
_IN____ const char a7[13],
_IN____ const char a8[21],
_INOUT_ char a1[513]
);
Now I wrote a test Python code to call C functions (accessible from cFunctions.py
). The issue is that , when I call "check" from my test code ( cFunctions.check(10,20)
) I reach it, but it never returns anything!
But if I call check
from within cFunctions.py
itself like this:
check(10,Trx.a2)
It returns the result. What am I doing wrong? Why check doesn't return anything when I'm calling it from my test.py ?
Does this help? A little Googling led me here!
Calling C functions from Python - By Christian Stigen Larsen
Reproducing the above link here for reference. I have not tested the code listed here. Also all the credit belongs to the author of the above link.
Here’s a small tutorial on how to call your C
functions from Python
.
Let's make some simple functions in C. We'll call the file
myModule.c
#include <Python.h>
/*
* Function to be called from Python
*/
static PyObject* py_myFunction(PyObject* self, PyObject* args)
{
char *s = "Hello from C!";
return Py_BuildValue("s", s);
}
/*
* Another function to be called from Python
*/
static PyObject* py_myOtherFunction(PyObject* self, PyObject* args)
{
double x, y;
PyArg_ParseTuple(args, "dd", &x, &y);
return Py_BuildValue("d", x*y);
}
/*
* Bind Python function names to our C functions
*/
static PyMethodDef myModule_methods[] = {
{"myFunction", py_myFunction, METH_VARARGS},
{"myOtherFunction", py_myOtherFunction, METH_VARARGS},
{NULL, NULL}
};
/*
* Python calls this to let us initialize our module
*/
void initmyModule()
{
(void) Py_InitModule("myModule", myModule_methods);
}
Compiling dynamic libraries on Mac OS X is different from the usual gcc -shared you might be used to:
gcc -dynamiclib -I/usr/include/python2.3/ -lpython2.3 -o myModule.dylib myModule.c
Now you have to do something awkward; rename myModule.dylib to myModule.so, so that Python will find the correct file (this is a bug in Python, it should've been fixed, but that's as far as I know):
mv myModule.dylib myModule.so
If you are using a system that supports -shared you can simply do this:
gcc -shared -I/usr/include/python2.3/ -lpython2.3 -o myModule.so myModule.c
On Windows you can reportedly type
gcc -shared -IC:\Python27\include -LC:\Python27\libs myModule.c -lpython27 -o myModule.pyd
Here's a simple program in Python to call your functions:
from myModule import *
print "Result from myFunction:", myFunction()
print "Result from myOtherFunction(4.0, 5.0):", myOtherFunction(4.0, 5.0)
The output is:
Result from myFunction(): Hello from C!
Result from myOtherFunction(4.0, 5.0): 20.0
If you are going to make bigger libraries available from Python I strongly suggest you check out SWIG or Boost Python.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With