Introducing the 'int' and 'string' arrays using ctypes (Python-> C ++)

I have a simple working program that sends an int ( num_piezas in the example) from a Python function to a C++ function.

foo.cpp

 #include <iostream> class Foo{ public: void bar(int number){ printf("Number is: %d\n", number); } }; extern "C" { Foo* Foo_new(){ return new Foo(); } void Foo_bar(Foo* foo, int number){ foo->bar(number); } } 

fooWrapper.py

 from ctypes import cdll lib = cdll.LoadLibrary('./libfoo.so') class Foo(object): def __init__(self): self.obj = lib.Foo_new() def bar(self, num_piezas): lib.Foo_bar(self.obj, num_piezas) num_piezas = 5 f = Foo() f.bar(num_piezas) 

The thing is, now I want to send an int array and a char array with this number. So I tried:

foo.cpp

 #include <iostream> #include <string.h> class Foo{ public: void bar(int number, int piezas[3], char prioridades[3][20]){ printf("Number is: %d\n", number); for(int i=0;i<3;i++) { printf("%d", piezas[i]); } for(int q=0;q<3;q++) { printf("%s ", prioridades[q]); } } }; extern "C" { Foo* Foo_new(){ return new Foo(); } void Foo_bar(Foo* foo, int number, int piezas[3], char prioridades[3][20]){ foo->bar(number, piezas, prioridades); } } 

fooWrapper.py

 from ctypes import cdll lib = cdll.LoadLibrary('./libfoo.so') class Foo(object): def __init__(self): self.obj = lib.Foo_new() def bar(self, num_piezas, piezas, prioridades): lib.Foo_bar(self.obj, num_piezas, piezas, prioridades) piezas = [1, 2, 3] prioridades = ['normal', 'baja', 'primera pieza'] num_piezas = 5 f = Foo() f.bar(num_piezas, piezas, prioridades) 

The C++ file compiles correctly, but when I try to execute the Python function ( python fooWrapper.py ), this error message appears:

 Traceback (most recent call last): File "fooWrapper.py", line 15, in <module> f.bar(num_piezas, piezas, prioridades) File "fooWrapper.py", line 9, in bar lib.Foo_bar(self.obj, num_piezas, piezas, prioridades) ctypes.ArgumentError: argument 3: <type 'exceptions.TypeError'>: Don't know how to convert parameter 3 

What am I doing wrong? Do I need to do something to pass int and string arrays as parameters? Thanks in advance.

+4
source share
2 answers

You can avoid this modification:

 from ctypes import c_int, c_char ... # create a 3-int array piezas = (c_int*3)() piezas[0] = 1 piezas[1] = 2 piezas[2] = 3 # create a 3-(20-char array) array prio = ((c_char*20)*3)() prio[0].value = "normal" prio[1].value = "baja" prio[2].value = "primera pieza" 

But since you are dealing with char arrays in the C ++ part, I would advise you to change the defintion function to: void Bar( int num, char* piezas, int len_piezas, char** prio , int len_prio_elem, int prio); . This is much longer, but you must control the length of the input arrays if you want to avoid buffer overflows.

+5
source

You need to define a function prototype using CFUNCTYPE (read the documents), and then wrap your function with a new type, after which you will get a typed function. You must do this every time you want to use a c function with args or a return type other than int.

http://docs.python.org/2/library/ctypes.html#function-prototypes

http://docs.python.org/2/library/ctypes.html#callback-functions

Python lists and c arrays are different. You can determine the type of c-array in python, read here:

http://docs.python.org/2/library/ctypes.html#arrays

+1
source

Source: https://habr.com/ru/post/1495716/


All Articles