【问题标题】:Using standard output from C library in C++ application在 C++ 应用程序中使用 C 库的标准输出
【发布时间】:2012-02-12 06:08:44
【问题描述】:

我有用 C 编写的代码,我正在努力创建一个库,我可以从中访问其他语言的函数。

我目前正在为此代码编写一个 C++ 客户端,以确定需要进行哪些更改才能支持将我的库包含到 C++ 应用程序中。

通常,基于 C 的二进制文件会分析一些输入,然后通过一系列 fprintf 语句将其数据输出到 stdout

有没有办法将相关 C 函数的输出重定向到stdout

我不是 C++ 专家,但我想我想做的是提供一个 C++ 输出流缓冲区的子类(ostreamofstream?),它包含相同的输出,否则会被发送通过相关的 C 函数到stdout

如果可能,我希望选择将此数据重定向到文件流或 C++ 应用程序中的标准输出。

我该怎么做?我可以保留我的 C 代码原样并从 C++ 代码中重定向 stdout 吗?

编辑

我可以编辑相关的 C 函数,以便将文件指针或描述符作为参数。这会有所帮助吗,能够传递输出的去向?我不清楚的是如何翻译 C++ IO 和 C IO。我不能将 C++ iostream 传递给 C 函数,或者我可以吗?

【问题讨论】:

  • 在某些系统(尤其是 Linux)上,来自 C 的 stdout 和来自 C++ 的 std::cout 是“同步的”。并且您始终可以在 C++ 代码中使用 <cstdio> 标头来获得 stdout 的 C 概念。
  • 因此,如果我设置 FILE *fp = stdout 并有一个 C 函数 foo(FILE *fp) 将数据吐出到 stdout,那么我将如何将输出从 std::cout 重定向到输出流(仍然)std::cout 还是文件输出流?
  • 一个 C 函数不知道 C++ std::cout !但见gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/manual/manual/…
  • 您使用的是 Unix / Linux / MacOS 吗?此外,仅将标准输出重定向到文件而不是以某种方式将其与 C++ 流组合就足够了吗?
  • 如何将套接字的一端传入库中,然后简单地写入该套接字并在客户端再次读取它?

标签: c++ c input stream


【解决方案1】:

在评论中我提到 C++ std::cout 和 C stdout 以一种棘手的方式相关联,您可以通过包含 <cstdio> 在 C++ 中使用 stdout。我还给出了以下链接:http://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/manual/manual/io_and_c.html

但是,您可以考虑更改库的 API,并提供写入用户提供的流和/或用户提供的文件路径的函数。

在 Linux 上,您还可以使用 open_memstreamfopencookie

【讨论】:

    【解决方案2】:

    如果我正确理解了您的问题,则不,至少使用符合标准的代码。

    可能相关的是 std::ios_base::sync_with_stdio ,它确保在某些 C++ 流上生成的 IO 与 C 流的 IO 生成正确同步。所以 stdout 与 cout 同步,stdin 与 cin 和 stderr 宽度 cerr 同步。但这并不是为了允许更改 cout 中的 streambuf 并将更改传播到 stdout(这是我理解您的请求的方式),如果您在 stdout 上执行 freopen,我还不确定预期的效果。

    【讨论】:

      【解决方案3】:

      您需要设置pipe,并将C 程序作为独立进程运行,其标准输出连接到管道的输入端。然后,您的 C++ 程序需要从管道的输出端读取数据,然后它将从 C 进程中获取所有输出。

      更新:在反对票和 cmets 之后,我重新阅读了这个问题。我(现在)意识到 C 代码作为库运行,即链接到与 C++ 代码相同的可执行文件。

      我不认为你可以强制重定向 C 代码的标准输出而不同时影响 C++ 程序的输出流,这似乎是为了拥有一个库而付出的非常高的代价。

      我仍然认为解决方案是在自己的进程中“沙箱化”C 代码,并使用重定向的输出,然后您可以根据需要读取该输出。当然,最好将 C 功能重写为 return 结果而不是打印它们,但我认为这不是一个选项。

      你说 C 代码使用fprintf(),即带有显式文件句柄的变体,所以也许你可以使用它并让它接受来自外部的FILE *,在这种情况下你可以给它一个管道无需对其进行子处理。

      非常有兴趣看到其他答案,也许我缺少一种方法。

      更新 2:如果您有机会控制将哪个 FILE * 传递到 C 库中,那么这很容易:

      • 要让输出与 C++ 程序的普通输出一起出现,只需传入 stdout
      • 要将输出捕获到文件,请fopen() 文件并传入生成的FILE *

      如果你想同时做both,那又有点麻烦了。在这种情况下,我会再次推荐一个管道或套接字,以便 C++ 端负责读取 C 库生成的输出,并用它做它想做的事情。

      【讨论】:

      • 但是 Alex Reynolds 写的是他的 C ,而不是 C 程序!
      • 这不是我想要的。我正在编写一个库,所以这一切都需要在应用程序中完成。
      • 用管道和套接字分别运行C程序不是我所追求的。我正在写一个,所以这一切都需要应用程序完成。
      猜你喜欢
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 2021-10-27
      • 2014-06-03
      • 1970-01-01
      相关资源
      最近更新 更多