4

我创建了用 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 列表?* 我清楚吗?谢谢提前

4

3 回答 3

6

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

#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 \Python27\include -L \Python27\libs -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]
>>>
>>>
于 2013-11-29T09:08:34.087 回答
1

使用 Visual Studio 和 Python 64 位:
1- 创建一个空的 Win32 项目(DLL 类型)
2- 右键单击​​您的解决方案项目 -> 配置管理器
3- 活动解决方案配置(发布)
4- 活动解决方案平台 -> 新建,然后在底部的下拉列表中,选择 x64 -> OK
5- 在 Source Files 文件夹中,添加一个空的 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;
}
于 2017-02-20T10:56:17.493 回答
0

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

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

    简而言之,你有这个“包装”DLL 调用你的函数。

  2. 但是,如果我现在再看一下您的问题,我发现您正在尝试通过ctypes. 这也是可行的,甚至可能更好,并且您必须使用ctypes.py_objectdata type

于 2013-11-29T08:45:42.757 回答