从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
时,这表明数组的数据类型没有正确传递给函数。
任何帮助都非常欢迎,这已经让我困扰了好几天!