how to deal with the PyObject* from C++ in Python

前端 未结 3 704
粉色の甜心
粉色の甜心 2021-01-03 09:06

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

相关标签:
3条回答
  • 2021-01-03 09:46

    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.

    0 讨论(0)
  • 2021-01-03 10:06

    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;
    }
    
    0 讨论(0)
  • 2021-01-03 10:11

    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]
    >>>
    >>>
    
    0 讨论(0)
提交回复
热议问题