无法在python

时间:2016-09-06 17:07:07

标签: python dll ctypes boost-python python-c-api

我试图用boost::python将C ++类公开给python,所以我要经历this tutorial。我使用以下源代码创建了一个visual studio .dll项目:

#include <boost/python.hpp>
using namespace boost::python;

struct World
{
    void set(std::string msg) { this->msg = msg; }
    std::string greet() { return msg; }
    std::string msg;
};

BOOST_PYTHON_MODULE(hello)
{
    class_<World>("World")
        .def("greet", &World::greet)
        .def("set", &World::set)
    ;
}

我将它构建为64位dll。本教程的下一步说:

  

在这里,我们编写了一个C ++类包装器,它公开了成员函数greet和set。现在,在将模块构建为共享库之后,我们可以使用Python中的World类。这是一个示例Python会话:

>>> import hello
>>> planet = hello.World()
>>> planet.set('howdy')
>>> planet.greet()
'howdy'

然而,在同一目录中启动python并输入import hello之后我得到了

>>> import hello
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'hello'
>>>

我尝试将'dll'文件重命名为hello.dll,并复制每个输出文件(dllexpilklibpdb)到%PYTHONPATH%\DLLs,但我仍然无法将模块导入到python中。

多次使用Google搜索引导我this article建议我使用ctypes导入dll。这允许我加载dll,但我仍然无法调用“World”类。例如:

>>> import ctypes
>>> mydll = ctypes.cdll.LoadLibrary("hello")
>>> mydll
<CDLL 'hello', handle 7fef40a0000 at 0x775ba8>
>>> hello = mydll.World()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python35\lib\ctypes\__init__.py", line 360, in __getatt
r__
    func = self.__getitem__(name)
  File "C:\Program Files\Python35\lib\ctypes\__init__.py", line 365, in __getite
m__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'World' not found
>>>

所以有几个问题:

  1. 是否可以使用ctypes在没有的python 中导入dll?该教程似乎表明它是,但没有提供有关将dll引入python的正确方法的详细信息。

  2. 我需要哪些文件以及在哪里?看起来我只需要在我的python shell的工作目录中使用visual studio中的dll文件,但这显然不适合我。

  3. 为什么我不能通过ctypes调用World

  4. 更重要的一些细节:我使用的是Windows 7 64位,python 3.5.2 64位,以及Visual Studio 2015和Boost 1.61。

1 个答案:

答案 0 :(得分:1)

我实际上在发布问题后不久就找到了答案。感谢this blog post我发现只需将#slice重命名为hello.dll即可。从更多的谷歌搜索,我认为 hello.pyd仅适用于C DLL,而不是C ++,而不适用于使用提升! ctypes的要点是删除对ctypes的需要并使DLL与python兼容。所以回答我自己的所有问题:

  1. 是的,但必须有boost::python分机。

  2. 您只需要已编译的.pyd文件和dll(可能会有所不同)。但是,就像我说的那样,必须重命名boost_python_vc140...dll文件。

  3. 因为ctypes不是加载dll dll的正确工具!