2010-08-24 78 views
4

首先,如果这个问题已经被问到或太天真,我表示歉意。我搜索了它并找不到它。是否将预处理器定义编译到库中?

它们(预处理器定义)是否被编译到静态/动态库中?例如,FBX SDK需要KFBX_DLLINFO。使用FBX SDK的库必须包含该库。现在,就我有限的实验而言,客户端应用程序不需要再次声明定义。

现在,我想不出一个更实际的情况,但如果客户端应用程序“需要”的定义,以排除(例如_CRT_SECURE_NO_WARNINGS与库编译什么,但如果我需要这些警告?

回答

16

简而言之:没有

在长: 在大多数情况下,你能想到的预处理器定义为文本替换机制编译时( -compilation)之前,他们进行处理,所以他们变换的源代码。就在编译器将其转换为机器代码,中间文件或其目标所在之处之前。当你有一个二进制lib/obj/dll/exe/so文件时,预处理器定义早已不复存在。

如果在作为库的一部分打包的代码中包含头文件(例如为了引用库定义的方法,类型,枚举等),那么您需要包含库定义的预处理器定义在那个头里。在你的情况下,如果你包含一个FBX头文件,你可能还需要使用KFBX_DLLINFO的预处理器定义。您链接的FBX二进制库几乎可以确定使用相同的头文件,因此您正在构建相同的定义。这是使用C/C++编写的库的常见模式:常见的共享头文件以及用于构建的静态或动态库。

+0

+1为可访问的解释,而不是一个是/否。 – 2010-08-24 08:04:57

+0

感谢您的详细解答,即击中头部! – Samaursa 2010-08-24 12:00:43

2

预处理器定义仅在编译期间存在。它们在编译后的二进制文件中不再存在,无论是静态还是动态库,还是可执行文件。

2

正如Chris解释的那样,#defines是一个文本替换机制。扩展传统上是作为预编译步骤执行的,主C++语言编译器没有(或不想)访问预替换文本。出于这个原因,#定义可以做一些C++基于语言的约束所无法做到的事情,例如连接值以形成新的标识符。目前,编译器倾向于嵌入宏处理功能,并且可能在编译为可执行文件的调试符号表中包含一些关于预处理器符号的信息。访问这些调试信息对于某些客户端使用来说不是很理想或实际,因为调试格式和内容可以在编译器版本之间改变,不是很便携,调试可能不是很好: - /,并且访问它们可能很慢,笨拙。

如果我正确理解你,你想知道你的库使用的一些低级库的#defines是否会自动提供给使用你的库的“应用程序”程序员。不,他们不会。您需要为您的库的API公开给应用程序员的那些值提供自己的定义(如果它们不同,则在内部映射到较低级别的库值),或者发送较低级别的库头。

有关重新映射的示例:

您的图书馆。H:

 
#ifndef INCLUDED_MY_LIBRARY_H 
#define INCLUDED_MY_LIBRARY_H 

enum Time_Out 
{ 
    Sensible, 
    None 
}; 

void do_stuff(Time_Out time_out); 

#endif 

你LIBRARY.C:

 
#include "my_library.h" 
#include "lower_level_library.h" 

void do_stuff(Time_Out time_out) 
{ 
    Lower_Level_Lib::do_stuff(time_out == Sensible ? Lower_Level_Lib::Short_Timeout, 
                : Lower_Level_Lib::No_Timeout); 
    LOWER_LEVEL_LIB_MACRO("whatever"); 
} 

如图所示,Lower_Level_Lib的使用还没有被暴露在my_library.h,因此应用程序的程序员并不需要了解或包括lower_level_library.h。如果您发现您需要/想将lower_level_library.h放入my_library.h中,以便在其中使用其类型,常量,变量或函数,则还需要为应用程序员提供该库标头。

+0

“您需要为您的库的API公开给应用程序员的那些值提供自己的定义(如果它们不同,则在内部映射到较低级别的库值),或者发送较低级别的库头。 - 正是我所困惑的。谢谢你们的出色解释。 – Samaursa 2010-08-24 12:03:05