静态 C 库中的选择性变量定义

Posted

技术标签:

【中文标题】静态 C 库中的选择性变量定义【英文标题】:selective variable definition in a static C library 【发布时间】:2018-09-11 13:27:47 【问题描述】:

我正在为基于 8051 微控制器的图形 LCD 制作 C 静态库文件 (.lib)。编译前可以选择一些功能和3种字体(只允许一种字体)。该库应包含一些不同的字体,例如:

#if defined FONT1
const uint8_t code font[size1] =  /* Font1 Data*/ 
#elif defined FONT2
const uint8_t code font[size2] =  /* Font2 Data*/ 
…

最终用户可以通过在给定的“.h”文件中定义来选择一种所需的字体。当我测试时,不可能通过将上面的代码编写为库文件来做到这一点,只需使用一种明显的已定义字体进行编译。另一方面,由于内存考虑,一次加载所有 3 种字体(在最终应用程序中)效率不高。 有合适的方法吗?

【问题讨论】:

每次你想要选择不同的字体时都必须重新构建所有内容,这是否违背了库的目的? @user463035818 该库包含所有字体。但最终应用程序选择仅加载一种字体。库大小无关紧要,程序大小才是。 【参考方案1】:

您可以将字体拆分到不同的源文件中。然后将每个源文件构建到一个单独的目标文件 (translation unit) 中,如果您的链接器足够好,它将丢弃包含未使用符号的目标文件。

如果未使用的目标文件被丢弃,那么其中的代码和数据当然不会成为最终链接的可执行文件的一部分。

【讨论】:

请注意,每个数组的名称需要不同,因此每个对象不会导出相同的符号。标头可用于确定要使用三个名称中的哪一个(例如,#defineing fontfont_afont_bfont_c,具体取决于预处理器定义)。 不能有font1、font2、font3,因为内部函数只写了“font”。也许我误解了,但是在最终应用程序中选择字体的机制是什么? @TirdadSadriNejad 看来您需要重新设计您的库。可以(并且应该,IMO)改变的一件事是您将字体作为参数传递给需要使用它的函数。这样,这些功能就变得独立于实际使用的字体。然后在使用库构建应用程序时很容易使用预处理器和条件编译来“选择”字体。 @Someprogrammerdude 的想法是正确的。每个源文件都定义了一个font 数组。该库现在将有多个具有相同font 变量的对象,并且在链接时将选择一个。要强制进行此选择,您可以在每个源文件中都有一个 init 函数,名称略有不同,然后从代码中调用此函数,即使该函数只是返回。这将强制链接器从库中选择具有该函数的对象。 还有另一种方法,即仍然为每个数组赋予其自己的变量名称,但使用链接器功能将名称 font 别名为头文件中的其中一个,具体取决于预处理器指令。如何做到这一点的细节——以及特定的编译器/链接器是否可以做到这一点,取决于编译器/链接器。

以上是关于静态 C 库中的选择性变量定义的主要内容,如果未能解决你的问题,请参考以下文章

C++ 静态库中的共享全局变量

VC中public定义的变量与全局变量的区别??

修改 Arduino 库中的静态变量

C中什么情况下把局部变量定义为局部静态变量

C语言全局变量(c文件和h文件中的全局变量静态全局变量)使用注意事项

C语言全局变量(c文件和h文件中的全局变量静态全局变量)使用注意事项