Boost.Python:__init__ 接受 None 参数

1 投票
1 回答
1716 浏览
提问于 2025-04-15 16:35

我有一个用Boost.Python封装的C++值类型,这个类型有一个NULL值的概念。相关的封装代码如下:

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

目前,在Python中尝试通过传递None__init__()方法来创建一个NULL实例,会导致C++的构造函数被调用时接收到一个无效的引用。也就是说,&arg == NULL

有没有办法在构造函数接收到None时捕捉到这个情况,并优雅地处理它,或者至少在我的程序崩溃之前抛出一个有意义的异常呢?

我使用的是Boost 1.36和Python 2.6.2。

1 个回答

2

添加一个 init<void*> 的重载会在使用 None 的时候传递 NULL,但我不太确定这会如何影响其他构造函数在一些特殊情况下的表现。我也没有得到你提到的那种 None 到字符串常量的转换,如果我不加 init<void*> 的话。我使用的是 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*>())
;
}
>>> import ex
>>> ex.A()
A::A()
<ex.A object at 0x839bf7c>
>>> ex.A(42)
A::A(long int)
<ex.A object at 0x839bfcc>
>>> ex.A("abc")
A::A(const std::string&)
<ex.A object at 0x839bf7c>
>>> ex.A(None)
A::A(void*)
<ex.A object at 0x839bfcc>

如果不加 init<void*>

>>> ex.A(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    A.__init__(A, NoneType)
did not match C++ signature:
    __init__(_object*, std::string)
    __init__(_object*, long)
    __init__(_object*)

撰写回答