引发异常:读取访问冲突**bp**为0xFFFFFFFFFFFF 我在C++项目中创建一个项目,希望得到NUMPY数组。我可以获得正确的NUM,但它报告读取访问冲突。这是我的python代码main.py import numpy as np import tensorflow as tf class PyInterface(object): def __init__(self): self.X = None self.Y = None def generate_np_uint8(self): np_array = np.random.randint(low=0, high=255, size=(2,2,2),dtype=np.uint8); print("Python, uint8:", np_array) return np_array def generate_np_float32(self): np_array = np.random.rand(2,2,2).astype(np.float32) print("Python, float:", np_array) return np_array if __name__ == '__main__': py = PyInterface(); py.generate_np_uint8(); py.generate_np_float32(); 这是我的扩展代码Python 的C++代码 public: float * CppPythonHandler::get_float() { return generate_np_float32(); } private: float * CppPythonHandler::generate_np_float32() { const int ND{3}; float *c_out = new float[8]; PyArrayObject *np_ret; PyObject* np_array = PyObject_CallMethod(interface, (const char*)"generate_np_float32", NULL, NULL); if (np_array) { np_ret = reinterpret_cast<PyArrayObject*>(np_array); if (PyArray_NDIM(np_ret) != ND) { std::cout << "Function returned with wrong dimension" << std::endl; Py_DECREF(np_array); Py_DECREF(np_ret); return c_out; } c_out[0] = *((float *)PyArray_GETPTR3(np_ret, 0, 0, 0)); c_out[1] = *((float *)PyArray_GETPTR3(np_ret, 0, 0, 1)); c_out[2] = *((float *)PyArray_GETPTR3(np_ret, 0, 1, 0)); c_out[3] = *((float *)PyArray_GETPTR3(np_ret, 0, 1, 1)); c_out[4] = *((float *)PyArray_GETPTR3(np_ret, 1, 0, 0)); c_out[5] = *((float *)PyArray_GETPTR3(np_ret, 1, 0, 1)); c_out[6] = *((float *)PyArray_GETPTR3(np_ret, 1, 1, 0)); c_out[7] = *((float *)PyArray_GETPTR3(np_ret, 1, 1, 1)); for (int i = 0; i < 8; ++i) { std::cout << c_out[i] << " "; } std::cout << std::endl; Py_DECREF(np_ret); Py_DECREF(np_array); return c_out; } else{ PyErr_Print(); Py_DECREF(np_array); Py_DECREF(np_ret); return c_out; } } 公共: float*CppPythonHandler::get_float(){ 返回generate_np_float32(); } 私人: float*CppPythonHandler::generate\u np\u float32(){ 常量int ND{3}; 浮动*c_out=新浮动[8]; PyArrayObject*np_ret; PyObject*np\u数组=PyObject\u调用方法(接口,(const char*)“生成\u np\u float32”,NULL,NULL); if(np_数组){ np_ret=重新解释(np_数组); 如果(PyArray_NDIM(np_ret)!=ND){ std::cout

引发异常:读取访问冲突**bp**为0xFFFFFFFFFFFF 我在C++项目中创建一个项目,希望得到NUMPY数组。我可以获得正确的NUM,但它报告读取访问冲突。这是我的python代码main.py import numpy as np import tensorflow as tf class PyInterface(object): def __init__(self): self.X = None self.Y = None def generate_np_uint8(self): np_array = np.random.randint(low=0, high=255, size=(2,2,2),dtype=np.uint8); print("Python, uint8:", np_array) return np_array def generate_np_float32(self): np_array = np.random.rand(2,2,2).astype(np.float32) print("Python, float:", np_array) return np_array if __name__ == '__main__': py = PyInterface(); py.generate_np_uint8(); py.generate_np_float32(); 这是我的扩展代码Python 的C++代码 public: float * CppPythonHandler::get_float() { return generate_np_float32(); } private: float * CppPythonHandler::generate_np_float32() { const int ND{3}; float *c_out = new float[8]; PyArrayObject *np_ret; PyObject* np_array = PyObject_CallMethod(interface, (const char*)"generate_np_float32", NULL, NULL); if (np_array) { np_ret = reinterpret_cast<PyArrayObject*>(np_array); if (PyArray_NDIM(np_ret) != ND) { std::cout << "Function returned with wrong dimension" << std::endl; Py_DECREF(np_array); Py_DECREF(np_ret); return c_out; } c_out[0] = *((float *)PyArray_GETPTR3(np_ret, 0, 0, 0)); c_out[1] = *((float *)PyArray_GETPTR3(np_ret, 0, 0, 1)); c_out[2] = *((float *)PyArray_GETPTR3(np_ret, 0, 1, 0)); c_out[3] = *((float *)PyArray_GETPTR3(np_ret, 0, 1, 1)); c_out[4] = *((float *)PyArray_GETPTR3(np_ret, 1, 0, 0)); c_out[5] = *((float *)PyArray_GETPTR3(np_ret, 1, 0, 1)); c_out[6] = *((float *)PyArray_GETPTR3(np_ret, 1, 1, 0)); c_out[7] = *((float *)PyArray_GETPTR3(np_ret, 1, 1, 1)); for (int i = 0; i < 8; ++i) { std::cout << c_out[i] << " "; } std::cout << std::endl; Py_DECREF(np_ret); Py_DECREF(np_array); return c_out; } else{ PyErr_Print(); Py_DECREF(np_array); Py_DECREF(np_ret); return c_out; } } 公共: float*CppPythonHandler::get_float(){ 返回generate_np_float32(); } 私人: float*CppPythonHandler::generate\u np\u float32(){ 常量int ND{3}; 浮动*c_out=新浮动[8]; PyArrayObject*np_ret; PyObject*np\u数组=PyObject\u调用方法(接口,(const char*)“生成\u np\u float32”,NULL,NULL); if(np_数组){ np_ret=重新解释(np_数组); 如果(PyArray_NDIM(np_ret)!=ND){ std::cout,python,c++,numpy,memory-management,Python,C++,Numpy,Memory Management,我遇到了相同的错误消息,几乎是偶然地修复了它 总结: 这似乎是由PyObject*的引用计数不正确引起的。 发生错误时使用的PyObject不一定是引用计数不正确的对象! 如果你还没有阅读,阅读可能会有所帮助 在我的例子中,我的C++是从python函数中读取pyObjt列表中的项目。但是,当从列表中读取这些项时,它们的ReFo计数没有增加,因为我调用的是 pyListGigMeTe()/而不是 pyStReSngGestMe()。这是一个正确的调试难题,因为错误是从运行PyObject\u C

我遇到了相同的错误消息,几乎是偶然地修复了它

总结: 这似乎是由PyObject*的引用计数不正确引起的。 发生错误时使用的PyObject不一定是引用计数不正确的对象! 如果你还没有阅读,阅读可能会有所帮助

在我的例子中,我的C++是从python函数中读取pyObjt列表中的项目。但是,当从列表中读取这些项时,它们的ReFo计数没有增加,因为我调用的是<代码> pyListGigMeTe()/<代码>而不是<代码> pyStReSngGestMe()。这是一个正确的调试难题,因为错误是从运行

PyObject\u CallFunction()
的完全不相关的代码部分抛出的

希望这有帮助

static int numargs=0;

static PyObject*
emb_numargs(PyObject *self, PyObject *args)
{
    if(!PyArg_ParseTuple(args, ":numargs"))
        return NULL;
    return PyLong_FromLong(numargs);
}

static PyMethodDef EmbMethods[] = {
    {"numargs", emb_numargs, METH_VARARGS,
     "Return the number of arguments received by the process."},
    {NULL, NULL, 0, NULL}
};

static PyModuleDef EmbModule = {
    PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods,
    NULL, NULL, NULL, NULL
};

static PyObject*
PyInit_emb(void)
{
    return PyModule_Create(&EmbModule);
}

int main(int argc, char *argv[]) {
    if (argc < 1) {
        fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
        return 1;
    }

    numargs = argc;
    PyImport_AppendInittab("emb", &PyInit_emb);

    Py_Initialize();        // initialize python interpreter
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("if not hasattr(sys, 'argv'):\n    sys.argv=['']");
    PyRun_SimpleString("sys.path.insert(0, \"./\")");
    PyRun_SimpleString("sys.path.insert(0, \"./venv/Lib\")");
    PyRun_SimpleString("sys.path.insert(0, \"./venv/Lib/site-packages\")");

    // instance cpp interface object
    CppPythonHandler * pInter = new CppPythonHandler("main", "PyInterface");
    // unsigned char * np_uint8 = pInter->get_uint8();
    float * np_float = pInter->get_float();

    std::cout<<"End test"<<std::endl;
    // delete []pInter;

    if (Py_FinalizeEx() < 0) {
        std::cout << "Fails to release" << std::endl;
        return 120;
    }
    system("pause");
    return 0;
}
CppPythonHandler::CppPythonHandler(const char* pModuleName, const char* pClassName) {
    interfaceModule = NULL;
    interfaceClass = NULL;
    interface = NULL;
    interfaceModule = PyImport_ImportModule(pModuleName);
    if (interfaceModule == NULL) {
        PyErr_Print();
        fprintf(stderr,"Fails to import the module.\n");
        Py_DECREF(interfaceModule);
    }
    else{
        // import interface class
        interfaceClass = PyObject_GetAttrString(interfaceModule, pClassName);
        if (interfaceClass && PyCallable_Check(interfaceClass)) {

            // NULL represents no args
            interface = PyObject_CallObject(interfaceClass, NULL);
            Py_DECREF(interfaceClass);
            Py_DECREF(interfaceModule);
            if(interface == NULL){
                fprintf(stderr,"Fails to instance interface.\n");
                Py_DECREF(interface);
            }
            std::cout<<"Initailization done"<<std::endl;
        }
        else{
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr,"Fails to import the class.\n");
            Py_DECREF(interfaceClass);
            Py_DECREF(interfaceModule);
        }
    }
}