我目前正在编写一个C / C ++共享库,该库计划成为另一个项目的扩展。在库中,我需要调用一些函数并访问原始代码的一些数据结构。显然,最明显的选择是包含原始代码中的标题,并让扩展的用户将pathes传递给头文件并构建库。为了简化构建过程,我考虑在单独的头文件中重写所需的函数声明。这可以被视为良好做法吗?那些没有分发源代码的库呢?我认为他们使用相同的方法。任何帮助表示赞赏!
答案 0 :(得分:1)
这可以被视为良好做法吗?
没有。运送您自己的标题意味着当标题不再与库 1 匹配时,您不会收到警告。结构类型可能会获得额外的成员,功能可能会改变像以前那样采用long
代替int
这样的小事情,不应该影响使用提供的标头的用户,但会严重影响自己写的用户。
唯一有意义的是,如果图书馆承诺ABI稳定,那么与旧图书馆版本相关联的已编译的第三方项目将继续有效。但这是例外,不是常态。
源代码未分发的库怎么样?我认为他们使用相同的方法。
如果A链接B,而A是封闭源,则A的作者仍然可以针对所有版本的B重新编译A.
如果A链接B,而B是闭源,B 仍然通常发送标题以允许用户使用它。
如果A链接B,而B是闭源,而不发送标题,那么通常情况下,它不会被设计为链接,并且无论如何都是非常坏主意。然而,在一些罕见的场景中,它确实有意义,并且为B和A自定义编写的标题可能是一个好主意。
1 当我写“库”时,我指的是与标题相关联的产品。对于插件,与标头关联的产品通常不会被称为库,但使用这些标头的代码可能是。
答案 1 :(得分:1)
您可以使用回调将主程序与库分开。
例如,可以计算某些东西的库。它可能是来自的数据 任何来源,但在这里它是从文件中读取:
<强> library.h 强>
struct FooCalc_S;
typedef struct FooCalc_S FooCalc_T;
typedef int (*Callback_T)(void * extra);
FooCalc_T * FooCalc_Create(Callback_T callback, void * extra);
int FooCalc_Run(FooCalc_T * fc); // Calls callback multiple times
<强>的main.c 强>
#include "library.h"
int ReadFromFile(void * extra) {
FILE * fp = extra;
// Reads next entry from file
return result;
}
int main(void) {
FILE * fp = // Open file here
FooCalc_T * fc = FooCalc_Create(ReadFromFile, fp);
int foo = FooCalc_Run(fc);