具有 extern #define 和 typedef 结构的静态库

Static Library with extern #define and typedef struct

我正在尝试创建一个静态库,其中库的某些方面可以在外部定义(在已编译的库代码之外)。

对于函数定义,我可以在库中使用 extern void foo() declarations 毫无问题地编译库,然后在引用静态库的代码中定义 foo() 的内容。

我还想做一些在静态库中的#define valuestypedef structs,可以在外部编辑。

如果删除#defines 或typedef structs declarations,则无法编译库。

所有使用 extern 的尝试也都失败了。

这可能吗?如果是这样,我该怎么做?

此致, 约翰.

看到#define是预处理器符号,所以在编译时会被原来的值替换掉。因此,将它们 extern 放入您的库中没有任何意义。

如果你想要某种编辑访问,那么使用编译器时间定义 对于 gcc 你可以使用 -D-U


对于 typedef 和结构定义,使用 extern 可以告诉 compile 它将在其他文件中定义,但是当您创建库时,该定义应该在那里。所以你想做什么是不可能的。

#defines 是在编译时处理的,所以你不能让这些在(编译的)库之外可编辑。

typedefs 和 structs 定义内存布局和这些数据类型的偏移量。这些在编译时处理以在编译代码中插入正确的偏移量以访问成员,因此也在编译时处理并且不能在(编译的)库之外编辑。

您可以将库函数 void * 指针传递给您的数据结构,并传递库函数来处理这些外部定义的数据类型。例如:

void genericSort(void *ArrayToSort, int (*cmp)(void *, void *));

在这里,您向库函数传递一个要排序的数组和一个比较两个元素的函数,而库对这个数组包含的内容一无所知。

对于 #define 值,您可以在库的 header 文件中将它们声明为外部常量,类似于函数。

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;

正如其他地方提到的,structtypedef 有点棘手。但是,您可以将它们分成库所需的位和应用程序使用的位。一种常用的技术是定义库所需的 header,它在末尾也有一个应用程序可以填写的 'generic' 标记。

// 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