简体   繁体   English

C / C ++外部函数声明

[英]C/C++ extern function declarations

I'm currently writing a C/C++ shared library which is planned to be an extension for another project. 我目前正在编写一个C / C ++共享库,该库计划作为另一个项目的扩展。 In the library, I need to call some functions and access some of the data structures of the original code. 在该库中,我需要调用一些函数并访问原始代码的某些数据结构。 Clearly, the most obvious option would be to include the headers from the original code and let the user of the extension pass the pathes to the header files and build the library. 显然,最明显的选择是包括原始代码中的标头,并使扩展名的用户将路径传递到标头文件并构建库。 In order to ease the build process, I thought about rewriting the required function declarations in a separate header file. 为了简化构建过程,我考虑过在一个单独的头文件中重写所需的函数声明。 Can this be considered good practice? 可以认为这是好的做法吗? What about libraries where the source code is not distributed? 没有源代码的库又如何呢? I would assume they use the same approach. 我认为他们使用相同的方法。 Any help is appreciated! 任何帮助表示赞赏!

Can this be considered good practice? 可以认为这是好的做法吗?

No. Shipping your own headers means you get no warning when the headers no longer match up with the library 1 . 不会。运送您自己的标题意味着标题不再与库1匹配时,您不会收到任何警告。 Structure types may get additional members, functions may change eg taking long instead of int like they used to, little things like that, that shouldn't affect users that use the provided headers, but will badly affect users that write their own. 结构类型可能会获得其他成员,功能可能会发生变化,例如花费long而不是像以前那样使用int等类似的小事情,这不会影响使用提供的标头的用户,但会严重影响编写自己的用户。

The only time it makes sense is if the library promises ABI stability, that already-compiled third-party projects linked against an older version of the library will continue working. 唯一有意义的是,如果该库保证ABI的稳定性,则与该库的较旧版本链接的已编译第三方项目将继续工作。 That's the exception, though, not the norm. 但是,这是例外,不是常规。

What about libraries where the source code is not distributed? 没有源代码的库又如何呢? I would assume they use the same approach. 我认为他们使用相同的方法。

If A links against B, and A is closed source, then A may still be recompiled by A's author against all versions of B. 如果A链接到B,并且A是封闭源,则A的作者仍可以使用B的所有版本重新编译A。

If A links against B, and B is closed source, B still typically ships headers to allow users to make use of it. 如果A链接到B,并且B是封闭源,则B通常仍会提供标头以允许用户使用它。

If A links against B, and B is closed source, and doesn't ship headers, then typically, it is not designed to be linked against, and doing so anyway is a very bad idea. 如果A链接到B,并且B是封闭源代码,并且附带标头,则通常情况下,它不是设计为可链接的,无论如何这样做是一个非常糟糕的主意。 In a few rare scenarios, however, it does make sense, and shipping custom-written headers for B along with A may be a good idea. 但是,在极少数情况下,这确实是有道理的,将B的自定义标题与A一起提供可能是个好主意。

1 When I write "library", I'm referring to the product associated with the headers. 1当我写“ library”时,是指与标题关联的产品。 In the case of a plug-in, it's possible that the product associated with the headers would typically not be called a library, but the code using those headers would be. 在使用插件的情况下,通常可能不将与标头关联的产品称为库,而将使用这些标头的代码称为库。

You could use callbacks to separate main program from library. 您可以使用回调将主程序与库分开。

For example, library which can calculate something. 例如,可以计算某些内容的库。 It could be data from any source, but here it is read from file: 它可以是来自任何来源的数据,但是这里是从文件中读取的:

library.h 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 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM