Converting a 2D numpy array to C ++ short **?

Therefore, I use python to call methods in the C ++ shared library. I have a problem converting a two-dimensional numpy array into a two-dimensional C ++ 2D array as input to a function. I have a toy example that shows a problem. Feel free to compile and try it out!

Here is the python code (soexample.py):

# Python imports from ctypes import CDLL import numpy as np # Open shared CPP library: cpplib=CDLL('./libsoexample.so') cppobj = cpplib.CPPClass_py() # Stuck on converting to short**? array = np.array([[1,2,3],[1,2,3]]) cpplib.func_py(cppobj,array) 

Here is the C ++ library (soexample.cpp):

 #include <iostream> using namespace std; class CPPClass { public: CPPClass(){} void func(unsigned short **array) { cout << array[0][0] << endl; } }; // For use with python: extern "C" { CPPClass* CPPClass_py(){ return new CPPClass(); } void func_py(CPPClass* myClass, unsigned short **array) { myClass->func(array); } } 

which I compile with the following command:

 g++ -fPIC -Wall -Wextra -shared -o libsoexample.so soexample.cpp 

When I run the python file, I get the following error:

 >> python soexample.py Traceback (most recent call last): File "soexample.py", line 13, in <module> cpplib.func_py(cppobj,array) ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: Don't know how to convert parameter 2 

How to fix this unsuccessful TypeError ?

+6
source share
1 answer

You can use ctypes c_short and POINTER to help with the intermediate conversion. The following function turns a numpy array into a C-type 2darray that can be passed into a C function expecting short ** .

 def c_short_2darr(numpy_arr): c_short_p = POINTER(c_short) arr = (c_short_p * len(numpy_arr) ) () for i in range(len(numpy_arr)): arr[i] = (c_short * len(numpy_arr[i]))() for j in range(len(numpy_arr[i])): arr[i][j] = numpy_arr[i][j] return arr 

Note. I changed func_py and CPPClass::func to take 2 additional parameters, the width and length of this array. In this case, CPPClass::func can print all the elements of the array:

 // ... void CPPClass::func(unsigned short **array, size_t w, size_t h) { for(size_t i = 0; i < w; ++i) { for(size_t j = 0; j < h; ++j) cout << array[i][j] << ", "; cout << '\n'; } } // ... void func_py(CPPClass *myClass, unsigned short **array, size_t w, size_t h) { myClass->func(array, w, h); } 

Using this helper function, the following should now work:

 >>> arr = numpy.array([ [1,2,3], [4,5,6] ]) >>> arr array([[1, 2, 3], [4, 5, 6]]) >>> cpplib.func_py(cppobj, c_short_2darr(arr), 2, 3) 1, 2, 3, 4, 5, 6, 0 
+4
source

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


All Articles