首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Boost Python 2:使用‘`std::string &’的构造函数

Boost Python 2:使用‘`std::string &’的构造函数
EN

Stack Overflow用户
提问于 2019-04-05 14:24:41
回答 2查看 246关注 0票数 0

我在C++中有一个遗留代码(这将是一个巨大的痛苦编辑),出于速度原因,我需要在Python2中使用它。

我有两堂课。一个负责从内存中以std::string的形式加载大量数据,并将其转换为内部表示形式的MiddleClass。第二种是将它从内部表示MiddleClass转换回std::string

代码语言:javascript
复制
 class Load {
     Load(const std::string & data) { ... };
     MiddleClass load() { ... };
 };

 class Save {
     Save(std::string & data) { .... };
     void save(const MiddleClass & middleclass) { ... };
 };

我的目标是在Python 2中使用这个设置,如下所示:

代码语言:javascript
复制
import datahandler # my lib
import requests

request = request.get("url-to-data")
loader = datahandler.Load(request.content) # my C++ class Load
internal_representation = loader.load()

.
.
.

result_variable = str() # or None or something not important
saver = datahandler.Save(result_variable) # my C++ class Save
saver.save(internal_representation)

我怎样才能做到这一点?

我从一开始就遇到了麻烦。

简单变体:

代码语言:javascript
复制
BOOST_PYTHON_MODULE(datahandler)
{
     class_<MiddleClass>("MiddleClass");\
     // some .defs - not important

     class <Load>("Load", init<const std::string &>())
         .def("load". &Load::load);

     class <Save>("Save", init<std::string &>())
         .def("save". &Save::save);        
}

将编译,不用担心,但是加载的数据不知何故被破坏了,这导致我认为我做的非常错误。

另外,我发现this有点离题,这告诉我,我不能拥有std::string &,因为Python是不可变的。

所以结论:我现在不知道该怎么办:(这里有人能帮我吗?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-09 13:59:07

所以,我找到了一个解决办法。证明我错了,但我认为,我想实现什么是不可能的。

Python具有不可变的字符串,因此将字符串的“引用”传递给函数并期望从函数内部更改字符串的能力是无效的。

以这段代码为例:

代码语言:javascript
复制
variable = "Hello"

def changer(var):
    var = "Bye"

changer(variable)

print(variable)

指纹“你好”。在Python中,您不能让它以不同的方式工作。(确切地说,它仍然是作为引用传递的,但是当您修改Python字符串时,您只需要创建一个新的引用和一个新的引用)。

,那么,如何绕过这件事呢?

很简单!创建一个C++包装器,它将处理传递std::string上的引用并返回结果字符串的副本。不是很有效,但你可能不能让它变得更好。

SaveWrapper类的示例代码:

代码语言:javascript
复制
class SaveWrapper {
    public:
       // some constructor
       std::string save(MiddleClass & value) {
           std::string result;

           Save saver(result);
           saver.save(value);

           return result;
       }
};

它可以很容易地“移植”到Python!

票数 0
EN

Stack Overflow用户

发布于 2019-04-05 15:32:17

以这个工作例子为参考。

  1. 定义您的C++类。例如:
代码语言:javascript
复制
class MiddleClass {
public:
    explicit MiddleClass(const std::string& data) : parent_data_(data) {}

    void print() {
        std::cout << parent_data_ << std::endl;
    }

private:
    std::string parent_data_;
};

class Loader {
public:
    explicit Loader(const std::string& data) :
        data_(data){

        };

    MiddleClass load() {
        return MiddleClass(data_);
    };

private:
    std::string data_;
};
  1. 创建boost绑定
代码语言:javascript
复制
boost::python::class_<MiddleClass>("MiddleClass",
     boost::python::init<const std::string&>(boost::python::arg("data"), ""))
     .def("print_data", &MiddleClass::print);

boost::python::class_<Loader>("Loader", 
     boost::python::init<const std::string&>(boost::python::arg("data"), ""))
     .def("load", &Loader::load);
  1. 将您的库安装在正确的python站点包中。
  2. 在python中享受它吧:
代码语言:javascript
复制
from my_cool_package import MiddleClass, Loader
example_string = "whatever"
loader = Loader(data=example_string)

# Get the middle class
middle_class = loader.load()

# Print the data in the middle class
middle_class.print_data()

预期产出:

代码语言:javascript
复制
whatever
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55537577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档