我正在尝试创建一个静态库,其中库的某些方面可以在外部定义(在编译的库代码之外)。
对于函数定义,我可以使用库中的extern void foo() declarations
编译库而不会出现问题,然后在引用静态库的代码中定义foo()
的内容。
我还想制作一些静态库中的#define values
和typedef structs
,可在外部进行编辑。
如果我删除#defines或typedef structs declarations
,那么我无法编译库。
所有使用extern的尝试也都失败了。
这可能吗?如果是这样,我该怎么办?
此致 约翰。
答案 0 :(得分:1)
#define
在编译时处理,因此您无法在(已编译)库外进行编辑。
typedef
和struct
定义了内存布局和这些数据类型的偏移量。这些在编译时处理,以在编译的代码中插入正确的偏移量以访问成员,因此也在编译时处理,并且不能在(编译的)库之外编辑。
您可以将库函数void *
指针传递给数据结构,并传递库函数来处理这些外部定义的数据类型。例如:
void genericSort(void *ArrayToSort, int (*cmp)(void *, void *));
在这里,您将库函数传递给一个数组进行排序,并将函数传递给两个元素进行比较,而不会让库知道这个数组的含义。
答案 1 :(得分:0)
请参阅#define
是预处理器符号,因此在编译时它将被其原始值替换。因此,在库中创建extern
没有任何意义。
如果你想要一些编辑类型的访问,那么使用编译时定义
对于gcc
,您可以使用-D
和-U
对于typedef和结构定义,使用extern可以告诉compile它将在其他文件中定义,但是当你在那时创建那个定义时应该存在。那么你想要做的就是它不可能。
答案 2 :(得分:0)
对于#define
值,您可以在库的头文件中将这些值声明为外部常量,类似于函数。
extern const int LIBRARY_USERS_VALUE;
这会强制应用程序代码声明常量本身,它也可以用#define
来声明。
// Value used by the library, and elsewhere in this code.
#define ARBITRARY_NUMBER 69
// Define the constant declared in the library.
const int LIBRARY_USERS_VALUE = ARBITRARY_NUMBER;
正如其他地方所提到的,struct
和typedef
有点棘手。但是,您可以将这些分成库所需的位和应用程序使用的位。常用的一种技术是定义库所需的标题,该标题也具有“通用”标题。应用程序可以填写的最后一个标记。
// Declare a type that points to a named, but undefined
// structure that the application code must provide.
typedef struct user_struct_tag* user_struct_pointer;
// Declare a type for a library structure, that refers to
// application data using the pointer to the undefined struct.
typedef struct
{
int userDataItemSize;
int userDataItemCount;
user_struct_pointer userDataPointer;
} library_type;
然后,应用程序代码必须声明结构(带有标记)本身。
// Define the structure referred to by the library in the application.
struct user_struct_tag
{
int dataLength;
char dataString[32];
};
// And typedef it if you need too.
typedef struct user_struct_tag user_data_type;
您可以使用许多其他类似的方法,前提是您的库无需了解应用程序代码中的数据结构。如果是,则在编译时需要向库提供该结构的声明。在这些实例中,您需要考虑库的实际用途,以及是否需要使用某种数据抽象来传递信息。例如,XML,TLV等