【问题标题】:Python ctypes. Get 2-dim arrayPython ctypes。获取二维数组
【发布时间】:2017-10-30 01:59:46
【问题描述】:

我有这个 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 中正确调用这个函数呢?

附:我“按原样”得到了这个库,所以最好在不重写 c++ 代码的情况下使用它。

【问题讨论】:

    标签: python c++ ctypes


    【解决方案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
       :
    

    【讨论】:

    • 太棒了!为什么手册没有包含如此清晰的示例。我在这个问题上花了很多时间。非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 2021-10-10
    • 1970-01-01
    相关资源
    最近更新 更多