5

I create DLL wrote in C++ , the exporting function returns PyObject * .Then I use ctypes to import the DLL in Python . Now , how can I get the real PyObject ??

here's some part of c++ code:

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; } 

and some python code :

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

*I wanna get the real python list containing 1,2,3,4...10 ? * Am I clear ?? Thanks advance

3

3 Answers 3

7

You have a number of issues of your code, some modifications:

#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; } 

compile it:

> g++ -Wall -shared lib.cpp -I \Python27\include -L \Python27\libs -lpython27 -o lib.dll -Wl,--add-stdcall-alias 

now you can load it as any function and set the getList return type to py_object as:

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

test it:

>>> 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] >>> >>> 
Sign up to request clarification or add additional context in comments.

3 Comments

thanks advance! learn from you , I modify my code , but finally return a python list like "[ " .btw,I use vs2010 to create the lib.dll. Does it metter??
I found a solution to my problem. I pass a pyobject list as parameter to c++ function, in the function I add items to the list. Finally ,it works
@Huhu: Hold the GIL for this. ctypes defaults to releasing the GIL. Use a function pointer type with the flag ctypes._FUNCFLAG_PYTHONAPI, or a subclass of the CDLL class with _func_flags_ = ctypes._FUNCFLAG_STDCALL | ctypes._FUNCFLAG_PYTHONAPI.
1

With Visual Studio, and Python 64 bits:
1- Create an empty Win32 Project (DLL Type)
2- Right Click on your Solution Project -> Configuration Manager
3- Active Solution configuration (Release)
4- Active Solution Platform -> New, then on the bottom Dropdown list, select x64 -> OK
5- In the Source Files Folder, add an empty C++ file
6- Put your C++ code (One modification for getList to be recognized)

#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; } 

Comments

0

I'm not exactly clear what you are asking. But I suppose you mean to ask what you can do now with your DLL.

  1. Well, in order to use it appropriately, you'll have to build a special DLL which directly can be imported as a module in Python. In order to determine what to do in order to use this, it is best you have a look for other modules, how they do it. E. g. MySQLdb could be a candidate.

    In short, you have this "wrapper" DLL call your function.

  2. But if I have a second look at your question now, I see that you are trying to load your DLL via ctypes. This is viable as well, maybe even better, and you'll have to use the ctypes.py_object data type.

1 Comment

I use "ctypes.py_object" and it works. excited~ Thank you very much

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.