无法在 python 中导入自定义 DLL
Unable to import a custom DLL in python
我正在尝试使用 boost::python
将 C++ class 公开给 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。教程的下一步说:
Here, we wrote a C++ class wrapper that exposes the member functions greet and set. Now, after building our module as a shared library, we may use our class World in Python. Here's a sample Python session:
>>> 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。
很多谷歌搜索让我 this article 推荐我使用 ctypes
来导入 dll
。这让我可以加载 dll
,但我仍然无法调用 "World" class。例如:
>>> 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。
实际上我是在发布问题后不久才想出答案的。感谢 this blog post,我发现只需将 hello.dll
重命名为 hello.pyd
就足够了。通过更多的谷歌搜索,我 认为 ctypes
仅适用于 C DLL,不适用于 C++,并且 not with boost!。 boost::python
的要点是消除对 ctypes 的需求并使 DLL 与 python 兼容。所以回答我自己的所有问题:
是,但必须有 .pyd
扩展名。
您只需要已编译的 dll
文件和 boost_python_vc140...dll
(可能会有所不同)。但是,正如我所说,dll
文件必须重命名。
因为 ctypes 不是加载 boost::python
dll 的正确工具!
我正在尝试使用 boost::python
将 C++ class 公开给 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。教程的下一步说:
Here, we wrote a C++ class wrapper that exposes the member functions greet and set. Now, after building our module as a shared library, we may use our class World in Python. Here's a sample Python session:
>>> 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。
很多谷歌搜索让我 this article 推荐我使用 ctypes
来导入 dll
。这让我可以加载 dll
,但我仍然无法调用 "World" class。例如:
>>> 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。
实际上我是在发布问题后不久才想出答案的。感谢 this blog post,我发现只需将 hello.dll
重命名为 hello.pyd
就足够了。通过更多的谷歌搜索,我 认为 ctypes
仅适用于 C DLL,不适用于 C++,并且 not with boost!。 boost::python
的要点是消除对 ctypes 的需求并使 DLL 与 python 兼容。所以回答我自己的所有问题:
是,但必须有
.pyd
扩展名。您只需要已编译的
dll
文件和boost_python_vc140...dll
(可能会有所不同)。但是,正如我所说,dll
文件必须重命名。因为 ctypes 不是加载
boost::python
dll 的正确工具!