Creating C++ API Library

Creating C++ API Library

本文关键字:Library API C++ Creating      更新时间:2023-10-16

我正在尝试理解正确的方法或正确的方法,以为非开放源项目提供合理的C API。我不想提供"仅标题"库,因为代码库相当大,打算是封闭的源。目标如下:

  • 提供一个本机C API,用户可以实例化C 类,并将数据传递到C 中,而无需CON c-forly Wraper
  • 允许方法作为参数并返回C 对象,尤其是STL类型(STD :: String,STD :: vector等(
  • 没有自定义分配器
  • 如果存在这样的标准,则大多数行业的标准/规范方法可以做到这一点
  • 没有重新创建com或使用MS com
  • 假设所有C 编译器至少均为C 11"兼容"

我针对窗口以及其他平台(Linux(。

我的理解是创建DLL或共享库,因为DLL边界问题是不可能的。要处理DLL边界问题,必须将DLL和调用代码与动态链接的运行时(以及Windows上正确的版本,多线程/调试/等(进行编译,然后所有编译器设置都需要相对于Debug符号(Debug符号(迭代器调试设置等(。我有一个问题是,如果在Windows上说,我们是否确保使用默认的"调试"answers" RESEREAS"设置在Visual Studio中匹配编译器设置,我们是否真的可以"安全"DLL以这种方式(即来回传递STL对象,并且如果不匹配不匹配,则肯定会危险/失败(?共享对象吗? *。

使用静态库可以解决此问题吗?编译器设置需要多少匹配静态库和链接的调用代码之间的匹配?它与DLL(在Windows上(几乎相同吗?

我试图在网上找到图书馆的示例,但对此找不到太多的指导。许多资源讨论了开源解决方案,该解决方案似乎正在将标题和实现文件复制到代码库中(仅适用于非标准(,该文件不适用于封闭源。

做到这一点的正确方法是什么?似乎这应该是一个普遍的问题。尽管我想知道大多数商业供应商是否仅使用C界面。

如果解决问题,我可以使用静态库。我还可以接受一个想法,即拥有一组具有Y设置变化的X编译器(其中X和Y是支持支持的选项列表(,并拥有生成X * y共享二进制库的构建系统,如果那样是"安全"。

答案实际上只是进行C接口或与工厂创建纯抽象接口?(如果是这样,是否有一本规范的书或指南进行此写作,这不是实现Microsoft com?(。

我知道Stefanus Dutoit的沙漏模式:https://www.youtube.com/watch?v=pvydhdm0q6y

我担心这是很多代码重复。

我不是在抱怨事物的状态,我只想理解"正确"的方式,希望这对其他人处于类似位置的人来说是一个好问题。

我已经审查了这些stackoverflow参考:

何时使用动态与静态库

如何安全地将对象,尤其是stl对象传递到dll?

分发Windows C 库:如何决定是创建静态还是动态库?

静态库API问题(STD :: String vs. Char*(

保证C 库的二进制兼容性的简便方法,C链接?

还审查了:

https://www.acodersjourney.com/cplusplus-static-vs-dynamic-libraries/

https://blogs.msmvps.com/gdicanio/2016/07/11/the-perils-of-cinterface-dlls/

鉴于您的要求,您需要在构建阶段链接到程序中的静态库(例如.lib(。

该库的接口将需要在声明类型和函数的标题文件中。

,如果您可以在零件之间管理依赖项,则可以选择将它们分配为一组库和标头文件。那是可选的。

您将无法定义自己的模板功能或类,因为(大多数编译器(需要为这些功能或类分发源。或者,如果这样做,您将无法将它们用作库的接口的一部分(例如,您可以在库中内部使用模板的功能/类,但不能将它们在库标题文件中曝光库(。

主要的下面是您需要为每个编译器和主机系统构建和分发库的版本(您支持的组合(。C 标准专门鼓励编译器之间的各种类型的不兼容性(例如,不同的名称乱码(,因此,一般而言,使用一个编译器构建的代码不会与与另一个C 编译器构建的代码相互键入。实际上,除非专门实施这些编译器(例如,两家供应商的协议(以外的编译器(例如,您的库都不与编译器一起使用(。如果您支持支持版本之间不同ABI的编译器(例如g++(,则您需要分发使用每个ABI版本构建的库版本(例如,支持每个ABI的编译器的最新版本(

一个上升空间 - 从为每个编译器和您支持的每个编译器建造库的构建 - 是,使用标准库(包括标准库中的模板类型或功能(将没有问题。通过论点将起作用。标准图书馆类型可以是您的课程的成员。这仅仅是因为库和使用它的程序将使用相同的编译器构建。

您需要正确地包括标准标头(例如,不依赖一个标准标头,包括另一个标准标头,除非标准说它实际上确实如此 - 某些库供应商对此并不严格,这可能会导致您的代码中断当使用不同的编译器及其标准库构建时(。

主要不需要您库的"调试"answers"发布"版本(或具有其他优化设置的版本(。一般而言,将程序的一部分与不同的优化设置进行编译没有问题。(如果您或使用库中的库中的程序员使用构建选项的异国情调组合,则可以使此类事情破裂,因此请将这些组合保持在最低限度(。分发图书馆的"调试"版本将允许使用debugger踏上图书馆,这似乎与您的愿望相反。

以上都不会阻止您使用自定义分配器,但也不需要它。

除非您真的愿意,否则您将不需要重新创建com。实际上,您应该旨在确保您的代码尽可能标准化 - 最大程度地减少编译器特定功能的使用,不要对类型的大小或类型的布局等特定假设。使用供应商特定的功能,例如com,-NO,除非您支持的所有目标编译器和系统都统一支持这些功能。哪个com不是。

我不知道是否有一种"标准/规范"的方式。编写适用于多个编译器和主机系统的代码是一项非平凡的任务,因为不同的编译器供应商如何解释或支持标准之间存在差异。保持代码很简单是最好的 - 您使用的语言或标准库功能越奇特或越多,您就越有可能在某些编译器中遇到错误。

此外,还要花一些时间为您的库设置测试套件,并定期维护它,以尽可能完整。使用该套件在您支持的编译器/系统的每个组合中测试您的库。

  • 提供一个本机C API,用户可以实例化C 类,并将数据传递到C 中,而无需CON c-forly Wraper

这不包括com。

  • 允许方法作为参数并返回C 对象,尤其是STL类型(STD :: String,STD :: vector等(

这不包括dlls

  • 如果存在这样的标准,则大多数行业的标准/规范方法可以做到这一点

不是"标准",但有共同的做法。例如,在DLL中,仅通过RAW C的内容。

  • 没有重新创建com或使用MS com

这需要DLL/COM服务器

  • 假设所有C 编译器至少均为C 11"兼容"

也许。通常是。

通常:如果要可用,请仅使用标头(如果模板(或H CPP。如果没有来源,最好的是DLL。静态库 - 您必须为许多编译器构建,并且必须在各处进行Lib,并且

在Linux上,GCC使用libstdc 作为C 标准库,而Clang可以使用libc 或libstdc 。如果您的用户使用Clang和Libc 构建,则仅使用GCC和LIBSTDC (LIBC 和LIBSTDC 不是二进制兼容(,他们将无法链接。因此,如果您不是要获得目标,则需要两个版本的库,一个用于libstdc ,另一个用于libc 。

此外,Linux上的二进制文件(可执行文件,静态库,动态库(在发行版之间不兼容。它可能会在您的发行版中使用,而不适用于其他人,甚至不适用于您的发行版。要非常小心地测试它是否可以针对哪个发行版。神圣的构建盒可以帮助您生产跨分布二进制文件。我听到了好消息,只是从未尝试过。最坏的情况您可能需要在您要支持的所有Linux发行版上构建。

https://phusion.github.io/holy-build-box/