gpt4 book ai didi

c++ - Boost.python 继承自包装类

转载 作者:行者123 更新时间:2023-11-30 03:00:21 25 4
gpt4 key购买 nike

我在使用 boost.python 为现有库创建 python 绑定(bind)时遇到了问题。场景如下:

#include<boost/python.hpp>

namespace bp = boost::python;

struct Base {
std::stringstream _myString;
Base() { };
Base(const Base& base) { _myString<<base._myString.str(); }

void getString(std::stringstream& some_string) {
_myString.str("");
_myString<<some_string.str();
std::cout<<"Got string: \""<<_myString.str()<<"\""<<std::endl;
}
};

struct BaseWrapper : Base,
bp::wrapper<Base>
{
BaseWrapper() :
Base(),
bp::wrapper<Base>() { };

BaseWrapper(const Base& base) :
Base(base),
bp::wrapper<Base>() { };

void getString(bp::object pyObj) {
std::string strLine = bp::extract<std::string>(pyObj);
std::stringstream sstrLine;
sstrLine<<strLine;
Base::getString(sstrLine);
}
};

struct Derived : Base
{
Derived() : Base() { };
Derived(const Derived& derived) : Base() { _myString<<derived._myString.str(); };
};

struct DerivedWrapper : Derived,
bp::wrapper<Derived>
{
DerivedWrapper() :
Derived(),
bp::wrapper<Derived>() { };

DerivedWrapper(const Derived derived) :
Derived(derived),
bp::wrapper<Derived>() { };
};

BOOST_PYTHON_MODULE(testInheritance){
bp::class_<BaseWrapper>("Base")
.def("getString", &BaseWrapper::getString);

bp::class_<DerivedWrapper, bp::bases<Base> >("Derived");
}

(抱歉代码块太长,这是我能想到的最小示例。)

您可以看到我必须覆盖 BaseWrapper 中的 getString() 方法,以便它可以处理 Python 字符串,这部分工作正常:

>>> import testInheritance
>>> base = testInheritance.Base()
>>> base.getString("bla")
Got string: "bla"
>>>

当我尝试从 Derived 的实例调用 getString 时,问题就出现了:

>>> derived = testInheritance.Derived()
>>> derived.getString("bla")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Base.getString(Derived, str)
did not match C++ signature:
getString(BaseWrapper {lvalue}, boost::python::api::object)
>>>

我能理解这里出了什么问题,但我不知道如何解决。如果有任何帮助,我将不胜感激!

最好的问候,爱 bean

最佳答案

问题是,DerivedWrapperBaseWrapper 没有关系。因此 DerivedWrapper 需要提供它自己的 python 改编的 void getString(bp::object pyObj) 实现。

所以让它工作的一种方法是这样的:

struct DerivedWrapper : Derived,
bp::wrapper<Derived>
{
DerivedWrapper() :
Derived(),
bp::wrapper<Derived>() { };

DerivedWrapper(const Derived derived) :
Derived(derived),
bp::wrapper<Derived>() { };

void getString(bp::object pyObj) {
std::string strLine = bp::extract<std::string>(pyObj);
std::stringstream sstrLine;
sstrLine<<"(from DerivedWrapper) "<<strLine;
Derived::getString(sstrLine);
}
};

[...]

bp::class_<DerivedWrapper, bp::bases<Base> >("Derived")
.def("getString", &DerivedWrapper::getString);

和输出

base = testInheritance.Base()
base.getString("bla")

derived = testInheritance.Derived()
derived.getString("blub")

符合预期

Got string: "bla"
Got string: "(from DerivedWrapper) blub"

关于c++ - Boost.python 继承自包装类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12202763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com