具有 extern #define 和 typedef 结构的静态库
Static Library with extern #define and typedef struct
我正在尝试创建一个静态库,其中库的某些方面可以在外部定义(在已编译的库代码之外)。
对于函数定义,我可以在库中使用 extern void foo() declarations
毫无问题地编译库,然后在引用静态库的代码中定义 foo()
的内容。
我还想做一些在静态库中的#define values
和typedef structs
,可以在外部编辑。
如果删除#defines 或typedef structs declarations
,则无法编译库。
所有使用 extern 的尝试也都失败了。
这可能吗?如果是这样,我该怎么做?
此致,
约翰.
看到#define
是预处理器符号,所以在编译时会被原来的值替换掉。因此,将它们 extern
放入您的库中没有任何意义。
如果你想要某种编辑访问,那么使用编译器时间定义
对于 gcc
你可以使用 -D
和 -U
对于 typedef 和结构定义,使用 extern 可以告诉 compile 它将在其他文件中定义,但是当您创建库时,该定义应该在那里。所以你想做什么是不可能的。
#define
s 是在编译时处理的,所以你不能让这些在(编译的)库之外可编辑。
typedef
s 和 struct
s 定义内存布局和这些数据类型的偏移量。这些在编译时处理以在编译代码中插入正确的偏移量以访问成员,因此也在编译时处理并且不能在(编译的)库之外编辑。
您可以将库函数 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;
正如其他地方提到的,struct
和 typedef
有点棘手。但是,您可以将它们分成库所需的位和应用程序使用的位。一种常用的技术是定义库所需的 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等
我正在尝试创建一个静态库,其中库的某些方面可以在外部定义(在已编译的库代码之外)。
对于函数定义,我可以在库中使用 extern void foo() declarations
毫无问题地编译库,然后在引用静态库的代码中定义 foo()
的内容。
我还想做一些在静态库中的#define values
和typedef structs
,可以在外部编辑。
如果删除#defines 或typedef structs declarations
,则无法编译库。
所有使用 extern 的尝试也都失败了。
这可能吗?如果是这样,我该怎么做?
此致, 约翰.
看到#define
是预处理器符号,所以在编译时会被原来的值替换掉。因此,将它们 extern
放入您的库中没有任何意义。
如果你想要某种编辑访问,那么使用编译器时间定义
对于 gcc
你可以使用 -D
和 -U
对于 typedef 和结构定义,使用 extern 可以告诉 compile 它将在其他文件中定义,但是当您创建库时,该定义应该在那里。所以你想做什么是不可能的。
#define
s 是在编译时处理的,所以你不能让这些在(编译的)库之外可编辑。
typedef
s 和 struct
s 定义内存布局和这些数据类型的偏移量。这些在编译时处理以在编译代码中插入正确的偏移量以访问成员,因此也在编译时处理并且不能在(编译的)库之外编辑。
您可以将库函数 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;
正如其他地方提到的,struct
和 typedef
有点棘手。但是,您可以将它们分成库所需的位和应用程序使用的位。一种常用的技术是定义库所需的 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等