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

asked Nov 29, 2013 at 8:34
3
  • 3
    Why not finish writing the module instead of using ctypes? Commented Nov 29, 2013 at 9:02
  • because I don't know what to do next...at that time Commented Nov 29, 2013 at 16:37
  • docs.python.org/2/extending/extending.html Commented Nov 29, 2013 at 17:15

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]
>>>
>>>
answered Nov 29, 2013 at 9:08
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;
}
answered Feb 20, 2017 at 10:56

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.

answered Nov 29, 2013 at 8:45

1 Comment

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

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.