Edit: Hello everyone !!
I'm currently trying to access C ++ functions from Python, and I ran into a problem when trying to pass a Python list as an argument to a function.
here is the definition of the C ++ function I'm trying to access (used to send a command to a PC / SC reader):
SRpdu *SendAPDU(unsigned int uiAPDU, //Command unsigned int ucLE, //Data expected for response unsigned int ucLC, //Size of data buffer unsigned char * pucDataBuf = 0); //data buffer
My goal is to call this function as follows from python, as in the example below. The goal is to convert the list [1,2,3] to unsigned char * buffer:
SendAPDU(0x01020304, 0, 3, [1, 2, 3])
The malfunction from the example "33.9.1 Converting a Python list to char **" from the SWIG documentation http://www.swig.org/Doc2.0/Python.html#Python_nn57 , I defined the following typemap to handle unsigned char * , but, Unfortunately, it looks like a generic card is not in use. In fact, I can only use the function with the last argument ignored or set to None.
Python Code:
>>> SendAPDU(0x02000000, 2, 0) [36864, [30, 240]] #This call is working >>> SendAPDU(0x02000000, 2, 0, None) [36864, [30, 240]] #Also working
Then, if I try to put a list for the command data (replacing None in the previous example), I get the following error:
>>> SendAPDU(0x02000000, 2, 4, [1, 2, 3, 4]) # HERE IT NOT WORKING Traceback (most recent call last): File "<stdin>", line 1, in <module> File "EMReaderEx.py", line 196, in SendAPDU def SendAPDU(self, *args): return _EMReaderEx.EMReaderEx_SendAPDU(self, *args) NotImplementedError: Wrong number or type of arguments for overloaded function 'EMReaderEx_SendAPDU'. Possible C/C++ prototypes are: EMReaderEx::SendAPDU(unsigned int,unsigned int,unsigned int,unsigned char *) EMReaderEx::SendAPDU(unsigned int,unsigned int,unsigned int) EMReaderEx::SendAPDU(SApdu &)
I think that we are here in the case of "Invalid argument type", so I assume that the type map is not used, because I think, but I'm not sure that the function is not called due to the parameter format not matching, So, the main question is how can I pass the list and be sure that it will be accepted by the function (and therefore caught on the map)?
I think I missed something because I did not find any working solution for this, and it should be used relatively often.
Here is the card code code in the SWIG.i file:
%typemap(in) unsigned char * { // Check if is a list unsigned char *ucBuf = NULL; if (PyList_Check($input) && PyList_Size($input) > 0) { int size = PyList_Size($input); int i = 0; ucBuf = (unsigned char *) malloc((size+1)*sizeof(unsigned char)); for (i = 0; i < size; i++) { PyObject *o = PyList_GetItem($input,i); if (PyLong_Check(o)) ucBuf[i] = (unsigned char) PyLong_AsLong(o); else { PyErr_SetString(PyExc_TypeError,"list must contain integers"); free(ucBuf); return NULL; } } } $1 = &ucBuf[0]; } %typemap(freearg) unsigned char * { if($1 != NULL) free( $1); }
In the Resume section, how to make a SWIG type map for calling a C ++ function:
SRpdu * SendAPDU(unsigned int uiAPDU, unsigned int ucLE, unsigned int ucLC, unsigned char * pucDataBuf);
Like this from python:
SendAPDU(0x02000000, 2, 4, [1, 2, 3, 4])
Any help is appreciated. Thanks in advance.
ps Sorry if my English is bad, this is not my native language.