我有这个c ++代码:
#define DLLEXPORT extern "C"
DLLEXPORT double **points(unsigned N, unsigned D)
{
double **POINTS = new double * [N];
for (unsigned i=0;i<=N-1;i++) POINTS[i] = new double [D];
for (unsigned j=0;j<=D-1;j++) POINTS[0][j] = 0;
// do some calculations, f.e:
// POINTS[i][j] = do_smth()
//
return POINTS
}
我使用这个命令编译:
g++ -shared gpoints.cc -o gpoints.so -fPIC
现在我想使用ctypes
从python调用此函数。我试过像这样的人:
mydll = ctypes.cdll.LoadLibrary('/.gpoints.so')
func = mydll.points
mytype = c.c_double * 3 * 10
func.restype = mytype
arr = func(10, 3)
print(arr)
当我尝试运行它时,我得到:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
[1] 2794 abort python3 test.py
那么,如何从Python中正确调用这个函数?
P.S。我“按原样”获得了这个库,因此,最好在不重写c ++代码的情况下使用它。
答案 0 :(得分:1)
您的restype
相当于double[10][3]
,但实际返回的是double**
:
#!python3.6
import ctypes as c
dll = c.CDLL('test')
dll.points.argtypes = c.c_int,c.c_int
dll.points.restype = c.POINTER(c.POINTER(c.c_double))
arr = dll.points(10,3)
for i in range(10):
for j in range(3):
print(f'({i},{j}) = {arr[i][j]}')
我使用以下DLL代码进行测试(Windows):
extern "C" __declspec(dllexport)
double **points(unsigned N, unsigned D)
{
double **POINTS = new double * [N];
for (unsigned i=0;i<=N-1;i++)
{
POINTS[i] = new double [D];
for(unsigned j=0;j<=D-1;j++)
POINTS[i][j] = i*N+j;
}
return POINTS;
}
输出:
(0,0) = 0.0
(0,1) = 1.0
(0,2) = 2.0
(1,0) = 10.0
(1,1) = 11.0
(1,2) = 12.0
(2,0) = 20.0
(2,1) = 21.0
: