【问题标题】:Disable/Remove printfs from library从库中禁用/删除 printfs
【发布时间】:2013-09-11 11:56:18
【问题描述】:

我们有一个供应商提供的库,它开启了 printfs。这是一个主要的烦恼,我们想以某种方式将其关闭或禁用。

有没有办法在不访问库源代码的情况下完全禁用此库中所有内容的 printfs?我们希望在应用程序的其他部分包含 printfs。

我们将 gcc 工具链用于嵌入式 (sh4) 平台。

谢谢!

【问题讨论】:

  • 什么是库的用例?如果是一个孤立的调用,那么您可以在它之前重定向标准输出,然后在它之后返回它。如果你有数千个调用,那么这个开销就太大了
  • 只有一处。如何将标准输出重定向到 null?
  • 需要一些代码,下面会单独写答案

标签: gcc embedded printf


【解决方案1】:

您可以破解库来调用虚拟包装函数,而不是真正的printf。以下是你的做法(假设库作为静态库分发):

  1. 创建一个名为wrap_printf.c 的文件,其内容如下:

    int __wrap_printf(const char *fmt, ...) {
        return 0;
    }
    
  2. 编译包装器:

    gcc wrap_printf.c -c -o wrap_printf.o
    
  3. 解压库:

    mkdir libobj; cd libobj; ar x libvendor.a
    
  4. 重新链接每个供应商对象文件以使用包装器:

    for obj in libobj/*.o; do ld --wrap=printf $obj -r -o $obj
    
  5. 重建库,包括包装器:

    ar rcs libvendor_noprintf.a wrap_printf.o libobj/*.o
    
  6. 像往常一样将您的程序与新库链接

    gcc program.o -lvendor_noprintf -o prog
    

【讨论】:

  • 我们在 Windows 上将 gcc 用于 sh 架构。我试过这个,但 id 没有用。在第 5 步之前一切正常,在第 5 步中,我得到一个小于输入存档的存档(2 MB 与 2.5 MB)。当我尝试编译它时,系统抱怨缺少功能:(
  • 好的。感谢您的帮助,我解决了这个问题。第五步,我没有调用你调用的命令,而是 ar cr libvendor.a libobj*.o wrap_printf.o 这并没有创建新库,而是将旧库中的所有文件替换为 .o 文件printf 已删除。现在它可以工作了:D
【解决方案2】:

在特定情况下,当您只有一个使用库的地方时,您可以使用freopen 来重定向标准输出。在 Linux 上试用此示例:

#include <stdio.h>

int
main(void)
{
  printf("This goes to screen\n");
  freopen("/dev/null", "w", stdout);
  printf("This goes to nowhere");
  freopen("/dev/tty", "w", stdout);
  printf("This goes to screen again\n");
  return 0;
}

这种方法的缺点是它依赖于平台。在 Windows 上,您必须使用 "NUL""CON" 设备而不是 "/dev/null""/dev/tty"

【讨论】:

  • 我们使用的不是linux,而是一些专有操作系统(称为OS21)。我试过了,但没有用:(
  • 您只需要知道 null 和 stdout 设备的符号名称。我不知道 OS21 是什么,如果没有关于它的设备名称的文档,那么同意,这将不起作用。
  • 我尝试了所有我能记住的方法,但没有成功。也许操作系统不支持重新打开标准设备)...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 2019-01-10
  • 1970-01-01
  • 2016-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多