代码之家  ›  专栏  ›  技术社区  ›  John

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

  •  2
  • John  · 技术社区  · 9 年前

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

    对于函数定义,我可以使用extern编译库而不会出现问题 void foo() declarations 在库中,然后定义 foo() 在引用静态库的代码中。

    我也想做一些 #define values typedef structs 它们在静态库中,可外部编辑。

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

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

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

    当做 厕所。

    3 回复  |  直到 9 年前
        1
  •  1
  •   Paul Ogilvie    9 年前

    #define s是在编译时处理的,因此不能在(编译的)库之外编辑这些。

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

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

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

    在这里,您向库函数传递一个要排序的数组和一个比较两个元素的函数,而库不知道这个数组包含什么。

        2
  •  0
  •   Evil Dog Pie    9 年前

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

    extern const int LIBRARY_USERS_VALUE;
    

    这迫使应用程序代码声明常量本身,它可以使用 #定义

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

        3
  •  0
  •   Jeegar Patel    9 年前

    看见 #define 是预处理器符号,因此在编译时,它将被其原始值替换。因此,制作它们没有任何意义 extern 在你的图书馆。

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


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