通过ctypes将numpy数组传递给c ++的问题

时间:2015-11-08 13:25:31

标签: python c++ c numpy ctypes

从Python开始,我想利用一种快速而复杂的算法,该算法将数组作为参数。代码是别人的c ++代码,后者又使用后端c代码。

界面看起来像这样(myfunc.cpp):

#include <Python.h>
#include <vector>

#define NO_IMPORT_ARRAY
#include <numpy/arrayobject.h>

extern "C" {
#include <my/myfunc.h>
}

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#include <iostream>

PyObject * myfunc(PyArrayObject & pyArray)
{
    std::cout << pyArray.descr << std::endl;
    std::cout << pyArray.descr->type_num << std::endl; //This fails to print, python crashes on my mac
    // check data type
    assert(pyArray.descr->type_num == PyArray_UBYTE);
    std::cout << pyArray.flags << std::endl;
    assert(pyArray.flags & NPY_FORTRAN);
    // ...
}

我已添加:

extern "C" {
    PyObject * run_myfunc(PyArrayObject & pyArray)
    {
        return myfunc(pyArray);
    };
}

我接下来不了解C或C ++,我也缺乏调试器设置。我已经成功编译了myfunc.cpp和myfunc.c文件,并创建了一个共享库。 接下来,我尝试将此共享库与python中的类型一起使用(ctypes以避免任何其他大型依赖项,例如boost)。

我在Python中尝试了许多不同的方法,每个方法的要点是:

import ctypes
import numpy as np

lib = ctypes.cdll.LoadLibrary('lib_myfunc.so')

# Approach 1
def myfunc():
    lib.run_myfunc.argtypes = [np.ctypeslib.ndpointer(dtype=np.uint8, flags="F_CONTIGUOUS", ndim=2)]
    data = np.ones((20, 20), order='F', dtype=np.uint8)
    return lib.run_myfunc(data)  # Python crashes here

# Approach 2:
def myfunc():
    data = np.ones((20, 20), order='F', dtype=np.uint8)
    c_uint8_p = ctypes.POINTER(ctypes.c_uint8)
    data_p = data.ctypes.data_as(c_uint8_p)
    return lib.run_myfunc(data_p)  # Python crashes here

python线程崩溃,说:

Exception Type:EXC_BAD_ACCESS (SIGSEGV)

这似乎发生在C ++代码试图访问pyArray.descr->type_num时,这表明数组的数据类型没有正确传递给函数。 任何帮助都非常欢迎,这已经让我困扰了好几天!

0 个答案:

没有答案