【发布时间】:2017-08-11 11:33:45
【问题描述】:
我正在尝试从 Python 调用 C++ .dll 并返回一个 numpy 数组。我正在使用
- Anaconda 2.7 x64
- Visual Studio 2013 更新 5
- 为 lib64-msvc-12.0 预构建的 boost 1.63.0
我设法从here 编译了这个简单的示例并在 Python 中运行它:
#include "stdafx.h"
#define BOOST_PYTHON_STATIC_LIB
#include <boost/python.hpp>
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(test)
{
using namespace boost::python;
def("greet", greet);
}
我不确定#define BOOST_PYTHON_STATIC_LIB,但没有它,python 无法打开 pyd 文件。我怀疑python无法解析动态构建中对MSVCR120.dll的引用,但我只是猜测。
下一步是添加<boost/python/numpy.hpp> 并遵循this 的指示,并从创建numpy::ndarray 开始。是的,我知道 void 与获取值的意图相矛盾,我只是想让事情尽可能简单。
#include <boost/python/numpy.hpp>
namespace p = boost::python;
namespace np = boost::python::numpy;
void getNPArray()
{
Py_Initialize();
np::initialize();
p::object tu = p::make_tuple('a', 'b', 'c');
np::ndarray const example_tuple = np::array(tu);
return;
}
导入和命名空间声明编译没有错误。
在下一步我遇到了链接器错误。虽然 Py_Initialize() 工作正常,但 np::initialize() 导致链接器抛出
错误 LNK2001:无法解析的外部符号“void __cdecl boost::python::numpy::initialize(bool)" (?initialize@numpy@python@boost@@YAX_N@Z)
而np::ndarray const example_tuple = np::array(tu) 会导致
错误 LNK2001:无法解析的外部符号“类 boost::python::numpy::ndarray __cdecl boost::python::numpy::array(class boost::python::api::object const &)" (?array@numpy@python@boost@@YA?AVndarray@123@AEBVobject@api@23@@Z)
由于链接器对第一个示例非常满意,我对这里发生的事情感到非常困惑。我还尝试注释掉第一个示例中的所有部分,并在没有任何行为变化的情况下编译第二部分。
非常感谢任何有关如何使我的链接器满意的提示。
[更新 - 问题已解决]
事实证明,错误的根源只是 boost 的 probuild 版本没有libboost_numpy-vc120-mt-1_63.lib,所以我按照here 的说明进行构建。使用此参数:
b2 -j8 --toolset=msvc-12.0 release link=static runtime-link=static address-model=64 --build-type=complete stage --with-python
现在为我工作的导入看起来像这样:
#define BOOST_PYTHON_STATIC_LIB
#define BOOST_LIB_NAME "boost_numpy"
#include <boost/config/auto_link.hpp>
#include <boost/python/numpy.hpp>
【问题讨论】:
-
boost build 根据是否执行 python -c "import sys; sys.stderr = sys.stdout; import numpy; print 来决定是否将boost-numpy库构建为boost-python库的一部分(numpy.get_include())" 成功与否。见github.com/boostorg/build/blob/…
标签: python c++ arrays numpy boost