我有一个用C++写的dll,我想导出到Python中以运行回归和单元测试(使用Python维护和运行回归更容易)。 为此,我想使用 Boost.Python 导出 dll 的主 API,以便它可以在 Python 中使用。 我的程序集如下所示:
- MyLibrary.dll//main API C++ Library
- MyLibrary.pyd//一个仅包含
BOOST_PYTHON_MODULE
导出定义的精简 dll 项目(依赖于 MyLibrary.dll) - ...//MyLibrary.dll所依赖的其他C++dll文件
我在让 MyLibrary.pyd 链接时遇到了一些麻烦,但在深入研究了一段时间后(例如在这里),我意识到我必须重新构建 boost,同时b2.exe
指向我的特定 Python 版本。之后,我能够从python导入并运行我的库(仅在我的机器上)。
技术数据:我正在使用boost 1.51,Windows 7 x64和MSVC-10.0上的Python 3.23构建库(我自己的项目是从VS2010构建的)。我用来与 boost 链接的变体是共享库,64 个地址模型,通过我自己的构建相应地发布。
问题是,当我尝试在另一台机器上导入库(在我的机器上构建)时,python抱怨:
ImportError: DLL load failed: The specified procedure could not be found.
在线import MyLibrary
这就引出了以下问题:
- 我在机器上构建的MyLibrary.pyd是"python可移植的"吗?这意味着,除了 3.23(我用来在我的机器上构建 boost.python 的版本)之外,它还能在 Python 的其他版本上运行吗?
- MyLibrary.pyd 的用户是否必须使用自己的 python 版本重新构建 boost 才能成功导入它?
- 到目前为止,我们一直在使用BoostPro提供的Windows的预构建的boost安装程序。该构建链接到哪个版本的 Python,如果我们只是决定在整个团队中使用"正确"的 Python 版本(BoostPro 链接的版本),我是否可以为我的用户省去自己构建 boost 的麻烦?
看看 PEP 384 在 http://docs.python.org/3.2/whatsnew/3.2.html。
http://www.boost.org/doc/libs/1_52_0/libs/python/doc/news.html 表明最近没有任何真正的进展,所以我怀疑Boost.Python是否支持或至少在定义Py_LIMITED_API的情况下进行了测试。
根据我使用 Boost.Python 和 PyCXX 的 Python 2.x 兼容性经验(我还没有使用 3.x 系列):
- 不,它不会。只有微版本更改保持 ABI 可移植性。
- 不完全是。您提供的 MyLibrary.pyd 二进制文件的用户将无法使用不同的主要/次要 python 版本加载它。她拥有的 Boost 的构建配置并不重要。你需要在你想要支持的每个次要Python版本中构建Boost.Python。这包括 32 位和 64 位 Python 安装的单独构建。
我的建议是尝试从定义Py_LIMITED_API源代码构建 Boost。我不保证它会成功,但值得一试。
如果失败了,请你的队友使用与你相同的Python版本,当然还有x64位Windows(因为.pyd本身就是64位)。或者更好地设置一台 CI 机器,它将在每个所需的配置中构建您的 python 模块,以便您的客户能够选择合适的二进制文件。让您的团队成员构建并使用他们自己的 MyLibrary.pyd 版本,仅供本地使用。