程序在Windows

时间:2017-02-16 11:56:11

标签: c++ windows dll boost-python

对不起,很长的帖子。我已经搜索了很多,但无法找到答案,所以在这里:

我正在使用C ++(BoostPython)开发Python扩展库。为了进行测试,我们有一个基于Python的测试工具,但我也想添加一个单独的C ++可执行文件(例如,使用BoostUnitTest或类似工具)来添加对库的进一步测试,包括测试未直接暴露给Python的功能。 / p>

我目前在Linux中运行它没有问题。我正在构建库,然后将其动态链接到使用BoostUnitTest的可执行文件。一切都按预期编译和运行。 但在Windows中,我遇到了问题。我认为在DLL边界上注册C ++ - > Python类型转换器可能会出现问题。 为了显示问题,我有以下示例: 在我的图书馆中我定义了:

namespace bp = boost::python;
namespace bn = boost::numpy;

class DLL_API DummyClass
{
public:
    static std::shared_ptr<DummyClass> Create()
    { 
        return std::make_shared<DummyClass>();
    }
    static void RegisterPythonBindings();
};
void DummyClass::RegisterPythonBindings()
{
    bp::class_<DummyClass>("DummyClass", bp::init<>())
        ;

    bp::register_ptr_to_python< std::shared_ptr<DummyClass> >();
}

其中DLL_API是Windows的常用_declspec(...)。我们的想法是,这个虚拟类将作为更大的Python模块的一部分导出

BOOST_PYTHON_MODULE(module)
{
    DummyClass::RegisterPythonBindings();
}

从链接到我的库的可执行文件中(省略包括等):

void main()
{   
    Py_Initialize();
    DummyClass::RegisterPythonBindings();
    auto myDummy = DummyClass::Create();
    auto dummyObj = bp::object( myDummy );
}

我在boost :: python ::对象中包装myDummy的最后一行在Windows中遇到了未处理的异常。从Python抛出异常(throw_error_already_set)。我相信(但可能是错误的)它没有为Python找到适当的C ++类型转换器,即使我调用了注册绑定。

KernelBase.dll!000007fefd91a06d()
msvcr110.dll!000007fef7bde92c()
TestFromMain.exe!boost::python::throw_error_already_set(void)
TestFromMain.exe!boost::python::converter::registration::to_python(void const volatile *)
TestFromMain.exe!boost::python::converter::detail::arg_to_python_base::arg_to_python_base(void const volatile *,struct boost::python::converter::registration const &)
TestFromMain.exe!main() Line 66
TestFromMain.exe!__tmainCRTStartup()
kernel32.dll!0000000077a259cd()
ntdll.dll!0000000077b5a561()

作为测试,我在主函数之前复制了在可执行文件中定义DummyClass的完全相同的代码,而不是链接到dll,这可以按预期工作。

我的模型是在边界的两侧使用嵌入式python编译为DLL,甚至可以在Windows中使用(这仅用于测试工具,因此我总是使用完全相同的工具链)。

非常感谢。

1 个答案:

答案 0 :(得分:0)

如果有人再次阅读此内容,Windows中的解决方案是将Boost编译为动态库并动态链接所有内容。我们不得不稍微改变代码的结构,但它现在有效。

Boost文档中有一个(小)引用声明在Windows中,Boost的动态lib版本有一个用于Python / C +之间转换的通用类型寄存器。 doc没有提到没有静态lib版本的通用寄存器(但我现在知道它不起作用)。