Поэтому я использую python для вызова методов в общей библиотеке C ++. У меня возникла проблема с преобразованием пустого 2D-массива в двумерный массив шортов C ++ в качестве входных данных функции. У меня есть созданный игрушечный пример, который демонстрирует проблему. Не стесняйтесь компилировать и попробовать!
Вот код Python (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)
Вот библиотека C ++ (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);
}
}
который я компилирую с помощью следующей команды:
g++ -fPIC -Wall -Wextra -shared -o libsoexample.so soexample.cpp
Когда я запускаю файл python, я получаю следующую ошибку:
>> 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
Как правильно исправить это несчастное TypeError
?
Ты можешь использовать ctypes
«s c_short
а также POINTER
чтобы помочь с промежуточным преобразованием. Следующая функция превращает пустой массив в 2-й массив типа C, который можно передать в функцию C, ожидающую 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
Обратите внимание, я изменил func_py
а также CPPClass::func
взять 2 дополнительных параметра, ширину и длину заданного массива. С этим, CPPClass::func
можно распечатать все элементы массива:
// ...
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);
}
С этой вспомогательной функцией теперь должно работать следующее:
>>> 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
Других решений пока нет …