如何集成开源C程序而不是通过系统调用调用其可执行文件?

时间:2010-12-25 18:31:02

标签: c++ c system fossil

我有一个可执行文件(fossil scm),我的程序通过:: CreateProcess windows调用从外部调用。然后捕获stdout和stderr。由于化石的源代码可用,我宁愿用它创建一个静态库并直接发出调用。目前,通过命令行参数完成与化石的通信,并且通过进程返回代码,stdout和stderr进行通信。 Fossil通过printf和fprintf调用写入stdout / err。

以最少的化石来源改变来解决这个问题的最佳方法是什么?是否有一种可靠的跨平台方法来拦截stdout / err并将其发送到内存缓冲区?

3 个答案:

答案 0 :(得分:3)

你说你想要

  

拦截stdout / err并将其发送到   内存缓冲区

这表明您不想为SCM程序引入API,而是希望在不更改现有代码的情况下继续解析文本输出。如果是这样,那么我认为改变现有方法是没有意义的。通过当前方法使用内存缓冲区和静态链接可以获得什么?

答案 1 :(得分:3)

您可以按照以下步骤执行此操作:

  • 将化石的主要功能重命名为其他内容,以便您可以将其称为
  • 在调用fossil的main之前,将stdout / stderr重定向到您选择的文件:

freopen("filename.out", "w", stdout);

  • 形成一个参数数组,调用fossil_main,从文件中读取输出。
  • 您需要恢复stdout流状态;没有跨平台机制,但您可以使用一些伪句柄(即Windows上的CONOUT $)。

但请注意,这很脆弱:

  • 可能有一些全局变量应该在main()的开头被零初始化,而对于第二次调用main()
  • 则不会这样。
  • fossil可能会更改某些进程/线程状态(区域设置,当前目录等),您将无法可靠地还原它。一个特别糟糕的情况是调用exit(n)。
  • 在进程终止时没有通常的清理 - 期望文件句柄保持打开状态(这样你就无法再次打开它们,如果它们在没有共享的情况下打开它们),内存泄漏等等。
  • 显然,现在化石中的崩溃/挂起将更难处理(你有时可以解决这个问题)

一般来说,你可以做到这一点,但除非你有充分的理由(即表现)并且你已经准备好面对后果并自己修复错误。

答案 2 :(得分:0)

将化石转变为共享库,然后使用自定义程序中的库。