Edit : Hi all !!
I'm currently trying to access to C++ functions from Python and I'm facing to a problem when I try to pass Python list as argument to a function.
here is the C++ function definition I'm trying to access (used to send command to 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 following from python like in example below. The goal is to convert the list [1,2,3] to a unsigned char * buffer :
SendAPDU(0x01020304, 0, 3, [1, 2, 3])
Insipired from example "33.9.1 Converting Python list to a char **" from SWIG documentation http://www.swig.org/Doc2.0/Python.html#Python_nn57, I defined following typemap to handle unsigned char *
but unfortunately it seems tha开发者_高级运维t the typemap is not used. Actually I can use the function only with 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 data of the command (replacing None in previous example), I receive the following error :
>>> SendAPDU(0x02000000, 2, 4, [1, 2, 3, 4]) # HERE IT'S 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 we are here in case of "Wrong type of argument", so I guess that the typemap is not used because I think, but not sure, that the function is not called because of the parameter format doesn't match. So the main question is how can I pass a list and be sure that will be accepted by the function (and therefore catched by the typemap) ?
I think I missed something because I didn't found any working solution for that, and it should relatively used often.
Here is the code of the typemap code in 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 Resume, how to do the SWIG typemap to call C++ function :
SRpdu * SendAPDU(unsigned int uiAPDU, unsigned int ucLE, unsigned int ucLC, unsigned char * pucDataBuf);
Like that from python:
SendAPDU(0x02000000, 2, 4, [1, 2, 3, 4])
Any help is welcome Thanks in advance
p.s. Sorry if my english is bad, it's not my native language.
You should look into module arrays.
In particular, you are looking to call fromlist
. If you are using a list to pass instead of a string just because you think that's what you should do, there is a string function available, fromstring
. Either way, you can simply initialize the array with format specifier 'B'
(notice that capital).
Example usage:
array ('B', [1, 2, 1, 0, 3, 6, 0, 6])
精彩评论