如何在Python中处理C++中的PyObject*



我创建了用C++编写的DLL,导出函数返回PyObject*。然后我用ctypes在Python中导入DLL。现在,我怎样才能得到真正的PyObject??

这是c++代码的一部分:

PyObject* _stdcall getList(){
    PyObject * PList = NULL;
    PyObject * PItem = NULL;
    PList = PyList_New(10);
    vector <int> intVector;
    int i;
    for(int i=0;i<10;i++){
        intVector.push_back(i);
    }
    for(vector<int>::const_iterator it=intVector.begin();it<intVector.end();it++){
        PItem = Py_BuildValue("i", &it);
        PyList_Append(PList, PItem);
    }
    return PList;
}

以及一些python代码:

dll = ctypes.windll.LoadLibrary(DllPath)
PList = dll.getList()

*我想得到包含1,2,3,4…10的真实python列表吗*我明白了吗??感谢提前

您的代码有很多问题,有些修改:

#include <Python.h>
#include <vector>
extern "C" PyObject* _stdcall getList(){
  PyObject *PList = PyList_New(0);
  std::vector <int> intVector;
  std::vector<int>::const_iterator it;
  for(int i = 0 ; i < 10 ; i++){
    intVector.push_back(i);
  }
  for(it = intVector.begin(); it != intVector.end() ; it++ ){
    PyList_Append(PList, Py_BuildValue("i", *it));
  }
  return PList;
}

编译:

> g++ -Wall -shared lib.cpp -I Python27include -L Python27libs -lpython27 -o lib.dll -Wl,--add-stdcall-alias

现在您可以将其加载为任何函数,并将getList返回类型设置为py_object为:

import ctypes
lib = ctypes.WinDLL('lib.dll')
getList = lib.getList
getList.argtypes = None
getList.restype = ctypes.py_object
getList()

测试它:

>>> import ctypes
>>>
>>> lib = ctypes.WinDLL('lib.dll')
>>>
>>> getList = lib.getList
>>> getList.argtypes = None
>>> getList.restype = ctypes.py_object
>>> getList()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
>>>

使用Visual Studio和Python 64位:
1-创建一个空的Win32项目(DLL类型)
2-右键单击解决方案项目->Configuration Manager
3-主动解决方案配置(发布)
4-活动解决方案平台->新建,然后在底部下拉列表中选择x64->确定
5-在源文件文件夹中,添加一个空的C++文件
6-放入您的C++代码(一次修改以识别getList)

#include <Python.h>
#include <vector>
extern "C" __declspec(dllexport) PyObject* _stdcall getList();
PyObject* _stdcall getList(){

    PyObject *PList = PyList_New(0);
    std::vector <int> intVector;
    std::vector<int>::const_iterator it;
    for (int i = 0; i < 10; i++){
        intVector.push_back(i);
    }
    for (it = intVector.begin(); it != intVector.end(); it++){
        PyList_Append(PList, Py_BuildValue("i", *it));
    }
    return PList;
}

我不太清楚你在问什么。但我想你的意思是问你现在可以用你的DLL做什么。

  1. 好吧,为了适当地使用它,你必须构建一个特殊的DLL,它可以直接作为Python中的模块导入。为了确定该做什么来使用它,你最好看看其他模块,它们是如何做到的。例如,MySQLdb可能是一个候选者。

    简而言之,你有这个";包装器";DLL调用您的函数。

  2. 但如果我现在再看一眼你的问题,我会发现你正试图通过ctypes加载你的DLL。这也是可行的,甚至可能更好,并且您必须使用ctypes.py_object数据类型。

最新更新