静态库结构和包括

问题描述 投票:2回答:1

我正在构建一个静态嵌入式C库,它有一个API头文件,列出了所有可用的功能。我不确定一些事情,我想在开始实施之前先澄清一下。

首先,由于这是一个嵌入式系统的C-Library,它有硬件FPU,我不知道应该包括什么来计算像sinf()等数学函数。通常我使用硬件特定包含,但是在这个静态C库中是不可用的,因为它可以在某些STM32或甚至某些AVR等上运行。如何解决这个问题?

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

当我在api.h中为foo.h定义必要的结构时,我需要在foo.h中包含api.h,在api.h中也包含foo.h,这不是我认为的好主意。

c static-libraries
1个回答
2
投票

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


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

举个例子,假设我们有四个文件:

  • 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

© www.soinside.com 2019 - 2024. All rights reserved.