通过Boost.Python传递函数引用

1 投票
1 回答
1369 浏览
提问于 2025-04-16 14:45

我在C++中有这样一个函数:

typedef boost::function<boost::shared_ptr<Object> (CL_DomElement*, std::string& desc)> Parser;
void registerParser(std::string type, Parser p);

// Later: exporting into python-module:
BOOST_PYTHON_MODULE(TypesManager)
{
    bp::def("RegisterParser", registerParser);
}

# Python code:
class TestObj(Object):
    @staticmethod
    def ParseTestObj(node, desc):
        pass

RegisterParser("test_obj", TestObj.ParseTestObj)

在Python代码中,这个对象是一个导出的类,它在C++代码中被用作类型定义(typedef)。

Boost.Python.ArgumentError: Python argument types in
    RegisterParser(str, function)
did not match C++ signature:
    RegisterParser(TypesManager {lvalue}, std::string, boost::function<boost::shared_ptr<Object> ()(CL_DomElement*, std::string&)>)

我哪里做错了?

1 个回答

1

我觉得Boost Python并不知道怎么把一个Python函数转换成boost::function对象。我建议可以使用一个代理来接收Python的可调用对象,然后模拟C++的接口。下面是一个简单的示例(当然,这个示例没有经过测试):

typedef boost::function<boost::shared_ptr<Object> (CL_DomElement*, std::string& desc)> Parser;
void registerParser(std::string type, Parser p);

struct ParserProxy
{
    bp::object callable;

    ParserProxy(bp::object callable)
    : callable(callable)
    { }

    boost::shared_ptr<Object> operator()(CL_DomElement* elem, std::string& desc)
    {
        bp::object obj = callable(elem, desc);
        return bp::extract<boost::shared_ptr<Object> >(obj);
    }
};

void registerParserByProxy(std::string type, bp::object callable)
{
    registerParser(type, ParserProxy(callable));
}

// Later: exporting into python-module:
BOOST_PYTHON_MODULE(TypesManager)
{
        bp::def("RegisterParser", registerParserByProxy);
}

撰写回答