静态库结构和包含
Static library structs and includes
我正在构建一个静态嵌入式 C 库,它有一个 API 头文件,其中列出了所有可用的函数。我不确定有几件事,我想在开始实施之前先澄清一下。
首先,因为这是一个用于嵌入式系统的 C 库,它有硬件 FPU,我不确定我应该包括什么来计算像 sinf() 等数学函数。通常我使用硬件具体包括,但在这个静态 C 库中不可用,因为它可以 运行 在某些 STM32 甚至某些 AVR 等上。我该如何解决这个问题?
进一步假设我有文件 foo.c 和 foo.h,它们在库中提供了一些隐藏函数,然后是 api.h,用户可以看到和 api.c,这也是隐藏的。在 foo.h 中现在定义了一些结构,我想 return 在给用户的回调中。由于这个结构是隐藏的,我不确定我应该如何处理这个回调。我是否应该在 api.c 中实现一个处理程序,它映射来自 foo.c 回调的结构并将它们传递给用户回调,其中结构在 api.h 中重新定义(使用不同的名称)或有没有开销更少的解决方案?
当我在 api.h 中为 foo.h 定义必要的结构时,我需要在 foo.h 中包含 api.h,而且 foo.h 在api.h,我认为这不是一个好主意。
对于问题的第一部分,像 sinf
这样的数学运算应该由 C 标准库处理(你应该检查你的特定版本以支持你的体系结构)。然后,您可以使用 math.h
header 及其函数,编译器应使用 FPU 进行浮点计算。
对于第二部分,向用户显示隐藏结构的通常方法是使用 foward 声明,但用户将不得不通过指针和访问函数与结构进行交互.
以你为例,假设我们有四个文件:
api.h
: public header
api.c
: 来自 public header 的函数的源代码
foo.h
: 库内部 header(不会运送到 end-user)
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
我正在构建一个静态嵌入式 C 库,它有一个 API 头文件,其中列出了所有可用的函数。我不确定有几件事,我想在开始实施之前先澄清一下。
首先,因为这是一个用于嵌入式系统的 C 库,它有硬件 FPU,我不确定我应该包括什么来计算像 sinf() 等数学函数。通常我使用硬件具体包括,但在这个静态 C 库中不可用,因为它可以 运行 在某些 STM32 甚至某些 AVR 等上。我该如何解决这个问题?
进一步假设我有文件 foo.c 和 foo.h,它们在库中提供了一些隐藏函数,然后是 api.h,用户可以看到和 api.c,这也是隐藏的。在 foo.h 中现在定义了一些结构,我想 return 在给用户的回调中。由于这个结构是隐藏的,我不确定我应该如何处理这个回调。我是否应该在 api.c 中实现一个处理程序,它映射来自 foo.c 回调的结构并将它们传递给用户回调,其中结构在 api.h 中重新定义(使用不同的名称)或有没有开销更少的解决方案?
当我在 api.h 中为 foo.h 定义必要的结构时,我需要在 foo.h 中包含 api.h,而且 foo.h 在api.h,我认为这不是一个好主意。
对于问题的第一部分,像 sinf
这样的数学运算应该由 C 标准库处理(你应该检查你的特定版本以支持你的体系结构)。然后,您可以使用 math.h
header 及其函数,编译器应使用 FPU 进行浮点计算。
对于第二部分,向用户显示隐藏结构的通常方法是使用 foward 声明,但用户将不得不通过指针和访问函数与结构进行交互.
以你为例,假设我们有四个文件:
api.h
: public headerapi.c
: 来自 public header 的函数的源代码
foo.h
: 库内部 header(不会运送到 end-user)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