使用 boost.python 时 c++ 流有啥问题?

Posted

技术标签:

【中文标题】使用 boost.python 时 c++ 流有啥问题?【英文标题】:what is wrong with c++ streams when using boost.python?使用 boost.python 时 c++ 流有什么问题? 【发布时间】:2010-12-06 01:10:03 【问题描述】:

更新 2:我不知道为什么这仍然被赞成(2014 年 3 月)。自从我多年前问过这个问题以来,这似乎已经解决了。确保您使用的是最新版本的 boost。

更新:也许 C++ 流需要初始化才能格式化数字,而在 Python 中加载共享库时初始化没有发生?

我在打电话

cout << 1 << "!" << endl; 

在通过 boost.python 导出到共享库的方法中。它不打印任何东西,但如果我这样做了

cout << "%" << "!" << endl; 

它有效。

这很重要,因为我想这样做:

ostream& operator <<(ostream &os, const Bernoulli& b) 
    ostringstream oss;
    oss << b.p() * 100.0 << "%";
    return os << oss.str();

我通过这样做暴露了这一点:

BOOST_PYTHON_MODULE(libdistributions)

    class_<Bernoulli>("Bernoulli")
        .def(init<>())
        .def(init<double>())

        .def("p", &Bernoulli::p)
        .def("set_p", &Bernoulli::set_p)
        .def("not_p", &Bernoulli::not_p)

        .def("Entropy", &Bernoulli::Entropy)
        .def("KL", &Bernoulli::KL)
        .def(self_ns::str(self))
    ;

但是当我在 python 中对 Bernoulli 对象调用 str 方法时,我什么也得不到。我怀疑更简单的 cout 问题是相关的。

【问题讨论】:

我对 iostreams 和 boost.python 没有问题...也许问题来自更微妙的错误?但是,文档中的技术 (1dl.us/dAD) 对我不起作用,我不得不写 .def("__str__", &amp;print_wrapper&lt;Bernouilli&gt;)self_ns 是什么?另外,在你的方法中,为什么不只是return os &lt;&lt; b.p() * 100.0 &lt;&lt; "%"; @rafak 这个问题解释了通过 ostringstream 进行操作的原因:***.com/questions/2249018/… @rafak print_wrapper 在哪里定义?我在 boost 中找不到它。 我应该说它是我的:template inline std::string print_wrapper(const C& obj) std::ostringstream os;操作系统 可能重复:***.com/questions/2828903/… 【参考方案1】:

我不久前也遇到过这个问题,使用 self_ns ,如Build problems when adding `__str__` method to Boost Python C++ classBuild problems when adding `__str__` method to Boost Python C++ class中的答案所述

这里使用self_ns的原因是Dave自己解释的http://mail.python.org/pipermail/cplusplus-sig/2004-February/006496.html


只是为了调试,请尝试

inline std::string toString(const Bernoulli& b) 

   std::ostringstream s;
   s << b;
   return s.str(); 

并将.def(self_ns::str(self))替换为

class_<Bernoulli>("Bernoulli")
[...]
.def("__str__", &toString)

【讨论】:

我使用了问题中的self_ns,并没有解决这个问题。 你能试试.def(self_ns::str(self_ns::self))吗? 你也可以尝试在你的 operator 嗨,我确实尝试了该代码。我很确定 Boost.Python 没有正确初始化流的整数到字符串代码。使用 printf 有效,但使用 ostream 无效。 @Neil G:你有没有试过我在“只是为了调试”下写的,有用吗?【参考方案2】:

您是否尝试过改用boost::format?由于您已经在使用boost,所以应该不会太麻烦。

boost::format( "%d%%" ) % ( b.p() * 100.0 )

另外,尝试将std::endl 显式传递给输出os

【讨论】:

谢谢。该数字仍未显示,但“%”符号在那里。似乎没有创建数字字符串化的缓冲区。 嗯。我会尝试重现问题。 谢谢。如果您无法重现它以及您是否找到了解决方案,请告诉我。 好吧,我写了一个空的Bernoulli类,p定义为double p() return 2.5;;在 Python 中,str(b) 按预期打印 250%。我使用了 boost 1.42 和 Python 2.5。您使用的是哪个版本? 我现在使用的是 boost 1.48 和 Python 3.1。【参考方案3】:

您是否尝试过在使用 .str() 方法之前刷新流?

oss << b.p() * 100.0 << "%" << std::flush;

【讨论】:

以上是关于使用 boost.python 时 c++ 流有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

使用 boost::python 从 c++ 函数访问大表

Boost.Python 如何拥有 C++ 类?

数据输入/输出流和缓冲输入/输出流有啥区别?

NodeJS:Duplex 流和 Transform 流有啥区别?

Boost python,嵌入时从python调用c++函数

使用boost python编译在python代码内部调用的c ++代码时出错