我正在建立一个静态嵌入式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,我认为这不是一个好主意
答案 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>