我试图用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
,并复制每个输出文件(dll
,exp
,ilk
,lib
和pdb
)到%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
>>>
所以有几个问题:
是否可以使用ctypes在没有的python 中导入dll
?该教程似乎表明它是,但没有提供有关将dll引入python的正确方法的详细信息。
我需要哪些文件以及在哪里?看起来我只需要在我的python shell的工作目录中使用visual studio中的dll
文件,但这显然不适合我。
为什么我不能通过ctypes调用World
?
更重要的一些细节:我使用的是Windows 7 64位,python 3.5.2 64位,以及Visual Studio 2015和Boost 1.61。
答案 0 :(得分:1)
我实际上在发布问题后不久就找到了答案。感谢this blog post我发现只需将#slice
重命名为hello.dll
即可。从更多的谷歌搜索,我认为 hello.pyd
仅适用于C DLL,而不是C ++,而不适用于使用提升! ctypes
的要点是删除对ctypes的需要并使DLL与python兼容。所以回答我自己的所有问题:
是的,但必须有boost::python
分机。
您只需要已编译的.pyd
文件和dll
(可能会有所不同)。但是,就像我说的那样,必须重命名boost_python_vc140...dll
文件。
因为ctypes不是加载dll
dll的正确工具!