我正在构建一个静态嵌入式C库,该库具有一个API头文件,其中列出了所有可用功能。我不确定几件事,在开始实施之前我想先澄清一下。
首先,由于这是具有硬件FPU的嵌入式系统的C库,因此我不确定要计算诸如sinf()等数学函数应包含的内容。通常我使用特定于硬件的包含,但是在静态C库中不可用,因为它可以在某些STM32甚至某些AVR等上运行。如何解决此问题?
进一步说,我有文件foo.c和foo.h,它们在库中提供了一些隐藏的功能,然后是api.h,用户可以看到它,而api.c也被隐藏了。现在在foo.h中定义了一些结构,我想在回调中返回给用户。由于此结构是隐藏的,因此我不确定如何处理此回调。我应该在api.c中实现一个处理程序,该处理程序将foo.c的回调中的结构映射到并将它们传递给用户回调,在api.h中重新定义结构(使用不同的名称),或者是否存在开销较小的解决方案?
当我在api.h中为foo.h定义必要的结构时,我需要在foo.h中包括api.h,但还要在api.h中包括foo.h,我认为这不是一个好主意。
对于问题的第一部分,类似的数学运算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
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句