【问题标题】:File Global Define文件全局定义
【发布时间】:2013-08-28 18:25:59
【问题描述】:

我正在制作一个小型库,我想为用户提供禁用他们不需要的部分的选项。

lib.h

#ifndef ONLY_BASICS
    void complexFunction(void);
#endif

lib.c

#ifndef ONLY_BASICS
    void complexFunction(void) {
        printf("damn, this is complex alright!\n");
    }
#endif

main.c

#define ONLY_BASICS
#include "lib.h"

我在其他库中看到过这样做,我缺少什么?

【问题讨论】:

  • “我错过了什么?”与您遇到的问题相关的问题?
  • 是的,即使设置了 ONLY_BASICS,我仍然可以调用该函数。
  • 问题是ONLY_BASICS只定义在main.c中。因此,lib.c 将定义 complexFunction。我认为您无法使用define 机制实现您所尝试的目标,并且仍然保持lib.h 通用。但是,当您编译时,它至少应该警告您正在尝试在没有函数原型的情况下调用 complexFunction。您还见过哪些其他库使用了这种技术?
  • 好的,现在我明白了这个问题。但是有解决办法吗?
  • 你能把#define ONLY_BASICS 放在lib.h 中吗?只要代码的其他部分不需要lib.c 中的复杂项目,它就可以工作。如果lib.c 正在为一些需要complexFunction 的模块提供服务,而另一些则不需要,那么您尝试做的事情作为编译时选项是无法实现的。 complexFunction 要么存在于你的构建中,要么不存在,它不能同时存在。

标签: c header c-preprocessor


【解决方案1】:

您可以让用户使用来自编译器的预置宏来控制构建,而无需编辑代码。如果您使用GCC,请使用开关-D,后跟宏名称。在 Microsoft compiler 上使用 /D 选项。

例如使用 GCC,我有:

#include <stdio.h>

int main(int argc, char **argv) {

#ifdef SAYHI
    #ifdef CAPITAL
    printf("HI\n");
    #else
    printf("hi\n");
    #endif
#elif SAYHELLO
    #ifdef CAPITAL
    printf("HELLO\n");
    #else
    printf("hello\n");
    #endif
#else
    #ifdef CAPITAL
    printf("SAY SOMETHING\n");
    #else
    printf("say something\n");
    #endif
#endif

    return 0;
}

用户可以通过-DMACRO启用和禁用他想要的东西,而无需编辑代码,例如:

$ gcc main.c
$ a.exe
say something
$ 
$ gcc main.c -DCAPITAL
$ a.exe
SAY SOMETHING
$ 
$ gcc main.c -DSAYHI -DCAPITAL
$ a.exe
HI
$ 
$ gcc main.c -DSAYHELLO
$ a.exe
hello
$ 

【讨论】:

    【解决方案2】:

    您似乎误解了库是什么以及它的用途。大多数(全部?)链接器已经通过不包含库中未引用的符号来完成您正在尝试的操作 - 这就是为什么使用 gcc,例如,您需要将库放在命令行的 end 之后包含对库函数的引用的源文件列表。

    您所做的似乎将此行为与库本身的编译时选项混淆了。在这种情况下,您可以像在lib.hlib.c 中一样使用#ifndef 块,但是您不需要在main.c 中做任何事情——在没有complexFunction 的情况下,该库已经构建好了。您可能希望让您的库构建过程生成一个标头来描述可用的功能。

    【讨论】:

    猜你喜欢
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 2016-05-01
    • 1970-01-01
    • 2022-10-19
    相关资源
    最近更新 更多