gpt4 book ai didi

c# - 为具有大量依赖项的库创建包装器的正确方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:15:54 25 4
gpt4 key购买 nike

假设我想为具有大量依赖项的大型库中的特定函数创建一个 c# 包装器。为了争论,假设我想为 CGAL 中的 convex_hull_3 函数创建一个 C# 包装器。图书馆。顾名思义,这个函数为 3D 空间中的一堆点创建了一个凸包。您可能已经知道,CGAL 依赖于一些其他库,例如 Boost MPFRGMP 以及其他一些库(它动态链接到这些库).
您将如何创建这样的包装器?包装函数的正确方法是什么,以便最终包装器最大限度地减少暴露/包装的其他库的数量?

我能想到的一种解决方案:

  1. 用 C++ 创建一个网关 项目。该网关项目具有 CGAL 的 DLL 以及 CGAL 需要工作的所有其他内容(增强 DLL、MPFR 的 DLL 等)作为依赖项。该项目有 2 个文件:一个头文件和一个 CPP 文件。这些文件声明了一个函数(例如)createConvexHull,它包装了原始的 convex_hull_3。此外,createConvexHull 函数被标记为 __declspec(dllexport)
    这个函数的要点是它改变了 CGAL 处理的数据的低级表示。例如,不必将点云数据声明为 CGAL 的内部数据类型之一,我们可以只传递一个表示 3D 数据 vector 的 double 组。因此,这个网关项目避免了包装 CGAL 的内部数据结构的需要,并暴露了最少量的额外依赖项。

  2. gateway 项目构建到 DLL 文件中(例如 CGAL-gateway.dll)。

  3. 用 C# 创建一个项目。我们将此项目称为包装器项目,因为所有 P/Invoke 操作都将在该项目内执行。添加 CGAL-gateway.dll 作为对该项目的引用以及 Boost DLL、MPFR DLL 和 GMP DLL .在这个项目中写下所有的 P/Invoke 东西。

  4. 构建 wrapper 项目并将其添加为您希望具有创建凸包功能的任何其他 C# 项目的引用。

潜在问题:

首先,我不知道这是否是执行此类操作的标准方法。为了个人/教育目的,我一生只创建了 2 个包装器,所以我所知道的大部分都是通过反复试验和查看其他人的代码学到的。
我发现这种方法的一个问题是会有一个额外的 C++ 项目(我指的是 gateway 项目),它相对无用,只能用作抽象层。这种方法的另一个问题是它创建了一个 DLL hell 。要将我的 C# 包装程序交给其他人,我必须给他们 BoostCGALMPFRGMP DLL 也是如此。运行我的包装器可能需要大量的 DLL。老实说,我什至不知道是否有解决办法。

我在考虑静态链接而不是动态链接,但这里有两个考虑因素。首先,我以前从未尝试过静态链接。其次,我认为您不能静态链接到 GPL v3 库。因此,如果我决定将来在开源许可下发布我的包装器,我将不得不坚持 GPL v3 许可(这不是我想要的)。

我不知道我是否能够以易于理解的方式表达我的问题。如果问题需要任何澄清,请告诉我。

最佳答案

有多种方法可以为 C# 的 native 库创建包装器。以下是其中的一些:

1- 创建一个混合模式程序集,在其中将您需要的功能从您的 native 库包装到一个 C++/CLR 类中,该类可以直接在 C# 中使用。这种方法的缺点是 your C# project will now be CPU-architecture-specific (免责声明:此链接指向我根据 SO 中的一些帖子加上我自己的经验编写的内容)。在您的 C++/CLR 包装器中,您将有“机会”将 native C++ 类型(如 std::string)转换为 C# 可以理解的类型(如 System.String)。

2- 在 C++ 中创建一个 COM 库,该库也可以直接在 C# 中使用。如果您可以在系统中全局注册该库,那么您的 C# 应用程序不需要特定于 CPU 体系结构。同样在这种情况下,来自 .net 框架的 COM-Interop 引擎将为您执行大部分类型编码(marshal)处理。

3- 创建一个带有导出函数的常规动态库,该函数总结了您需要的功能并且可以使用 DllImport 从 C# 调用属性,或来自 Windows API 的 LoadLibrary/FreeLibrary/GetProcAddress 函数。我相信这就是您在问题中描述的方法,并且您添加了一个额外的 C# 包装器层,我认为最好将其作为示例代码/文档提供。

没有一种方法是对的或错的,在每一种方法中,您都可以动态或静态地链接其余的依赖项。

顺便说一句,如果你的依赖项被许可为 GPL-v3,我认为 there is no way for you to distribute these dependencies while complying with the GPL-v3 license .

关于c# - 为具有大量依赖项的库创建包装器的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33639992/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com