静态库结构,包括

汉斯·彼得·阁楼

我正在构建一个静态嵌入式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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章