静态库结构,包括

时间:2019-03-24 09:01:01

标签: c static-libraries

我正在建立一个静态嵌入式C库,其中包含一个API头文件,其中列出了所有可用功能。我不确定几件事,在开始实施之前我想先澄清一下。

首先,由于这是用于嵌入式系统的C库,具有硬件FPU,因此我不确定计算诸如sinf()等数学函数时应包含的内容。通常,我使用硬件特定的include ,但这在静态C库中不可行,因为它可以在某些STM32甚至某些AVR等上运行。我如何解决此问题?

进一步说,我有文件foo.c和foo.h,它们在库中提供了一些隐藏的功能,然后还有api.h,用户和api.c都可以看到,而api.c隐。现在在foo.h中定义了一些结构,我想在回调中返回给用户。由于此结构是隐藏的,因此我不确定如何处理此回调。我应该在api.c中实现一个处理程序,该处理程序将foo.c的回调中的结构映射到foo.c并将其传递给用户回调,在api.h中重新定义结构(使用不同的名称),或者是否存在开销较小的解决方案?

当我在api.h中定义foo.h的必要结构时,我需要在foo.h中包括api.h,但还要在api.h中包括foo.h,我认为这不是一个好主意

1 个答案:

答案 0 :(得分:2)

对于问题的第一部分,sinf之类的数学运算应由C标准库处理(您应检查特定版本以获取体系结构的支持)。然后,您可以使用math.h标头及其函数,然后编译器应使用FPU进行浮点计算。


对于第二部分,向用户显示隐藏结构的通常方法是使用前向声明,但是用户将不得不通过指针和访问函数与该结构进行交互。

以您的示例为例,假设我们有四个文件:

  • api.h:公共标题
  • api.c:来自公共标头的函数的源代码
  • foo.h:库内部标头(不会传送给最终用户)
  • foo.c:内部函数的源代码

api.h是其中唯一有趣的文件(没有任何更改)。

// file: api.h
#ifndef API_H
#define API_H

struct foo; // forward declaration of the foo structure

typedef void (*callback_t)(struct foo*); // typedef for a callback taking a
                                         // struct foo argument

void set_callback(callback_t fn);
#endif

现在我们有了回调的类型和给回调的结构的类型,但是用户无法与结构本身进行交互,因为编译器仅知道它的存在但不知道其内容(也不知道存储大小)

当用户像下面的代码中那样编写回调时,用户将需要具有一些访问功能。

#include "api.h"

void user_callback(struct foo* arg) {
    // user code here
}

访问功能通常是这样定义的:

// in the file api.h or another header that the user has access to

int foo_get_value1(struct foo* arg);
void foo_set_value1(struct foo* arg, int new_value);

,这些功能将在foo.c

中实现
struct foo {
    int value1;
    int value2;
};

int foo_get_value1(struct foo* arg) {
    return arg->value1;
}

void foo_set_value1(struct foo* arg, int new_value) {
    arg->value1 = new_value;
}

这种方法的另一个优点是您的foo_set函数可以进行有效性检查,以确保结构中具有适当的值。

请注意:我没有在我的访问函数中添加任何检查以免使代码混乱,但是在将指针传递给函数时,应始终对其进行检查NULL < / p>