【问题标题】:Boost.Python: __init__ accepting None argumentBoost.Python:__init__ 接受 None 参数
【发布时间】:2009-12-02 05:50:48
【问题描述】:

我有一个用 Boost.Python 包装的 C++ 值类型,它有一个 NULL 值的概念。包装代码的相关部分如下所示:

class_<TCurrency> currency( "TCurrency" )
    .def( init<long>() )
    .def( init<const std::string&>() )
    <...>;

目前,尝试通过将 None 传递给 __init__() 方法在 Python 中创建 NULL 实例会导致接受 const 字符串引用的 C++ ctor 以无效引用被调用。 (&amp;arg == NULL)

是否可以捕获None 被传递给构造函数的情况并优雅地处理它,或者至少在我的程序崩溃之前抛出一个有意义的异常?

使用 Boost 1.36 和 Python 2.6.2。

【问题讨论】:

    标签: python crash boost-python


    【解决方案1】:

    如果使用 None,添加 init&lt;void*&gt; 重载将传递 NULL,但我不确定这会如何影响极端情况下的其他 ctor。如果我离开init&lt;void*&gt;,我也没有得到您提到的相同的 None to string const& 转换。使用 Boost.Python 1.37 和 Python 2.6.2。

    例子:

    #include <iostream>
    #include <string>
    
    #include <boost/python.hpp>
    
    
    struct A {
    #define BODY { std::cout << __PRETTY_FUNCTION__ << '\n'; }
        A() BODY
        A(long) BODY
        A(std::string const&) BODY
        A(void* p) BODY
    #undef BODY
    };
    
    BOOST_PYTHON_MODULE(ex) {
    using namespace boost::python;
    class_<A>("A")
        .def(init<long>())
        .def(init<std::string const&>())
        .def(init<void*>())
    ;
    }
    
    >>> 进口前 >>> ex.A() A::A() >>> ex.A(42) A::A(长整数) >>> ex.A("abc") A::A(const std::string&) >>> ex.A(无) A::A(无效*)

    如果init&lt;void*&gt; 被忽略:

    >>> ex.A(无) 回溯(最近一次通话最后): 中的文件“”,第 1 行 Boost.Python.ArgumentError:Python 参数类型在 A.__init__(A, NoneType) 与 C++ 签名不匹配: __init__(_object*, std::string) __init__(_object*, long) __init__(_object*)

    【讨论】:

    • 看起来应该有一个适配器或类似的你应该能够应用,例如,让 A(None) 使用默认 ctor。很高兴你问了这个问题,我期待着更详细的答案。 (来自其他人.. >
    • 有趣。我真的不想修改原始 C++ 类以接受 void*,但我试图在类之外定义一个 init。它实际上并没有正确创建对象(这将是另一个问题的主题),但至少我得到了 Python tb 而不是崩溃。耶! =]
    猜你喜欢
    • 2013-12-24
    • 2018-01-28
    • 1970-01-01
    • 2016-02-03
    • 2018-12-23
    • 1970-01-01
    • 2013-01-13
    • 2014-10-19
    • 2020-01-30
    相关资源
    最近更新 更多