用于包装C库的P/Invoke或C++/CLI

Ian*_*n G 34 .net c# pinvoke c++-cli

具有中等大小(40多个函数)的C API,需要从C#项目调用.这些函数在逻辑上分解,形成一些类,这些类将呈现给项目的其余部分.

在稳健性,可维护性,部署......方面,是否有任何客观理由倾向于使用P/Invoke或C++/CLI来实现该API下的互操作性?

我能想到的问题可能是,但没有问题的是:

  • C++/CLI将需要单独的程序集,P/Invoke类可以在主程序集中.(我们已经有多个程序集,无论如何都会有C dll,所以不是主要问题).
  • 两种方法之间的性能似乎没有明显差异.

我不确定的问题是:

  • 我的感觉是,如果存在操作间问题,C++/CLI将更容易调试,这是真的吗?
  • 语言熟悉程度足以让人知道C#和C++,但是对C++/CLI细节的了解却很少见.

还要别的吗?

Jar*_*Par 17

在我使用现有C库的情况下,我更喜欢PInvoke.PInvoke虽然有时候有点乏味和麻烦,但它是一种相当容易理解的技术,它拥有越来越多的工具和互联网文档.一般来说,无论遇到什么问题,网上都有可用的样本,或者快速检查堆栈溢出将提供解决方案.

C++/CLI是一项很棒的技术,但是对于互操作特定情况,恕我直言,其文档与PInvoke相比是有限的.它也没有PInvoke所具有的互操作解决方案的工具基础结构.为可以使用PInvoke解决的场景添加C++/CLI程序集对我来说似乎太昂贵了.

另一方面,如果我正在使用大型C++库,我会更多地考虑C++/CLI.PInvoke不能与C++一起使用,我最终必须添加某种中间层.要么包含所有C++函数调用的小C层,要么用C++/CLI库来弥补差距.在这种情况下,C++/CLI对我来说感觉更自然一些.


Ben*_*igt 8

这在很大程度上取决于如何处理内存所有权.只有当内存管理是几种特定方式之一(通常是调用者分配的缓冲区)时,P/invoke才能编组指针.如果你的API返回指针(通过返回值或输出参数,无所谓)并期望它们稍后被交还给销毁函数... p/invoke将执行自动编组或直接访问指针您需要稍后发回的价值,而不是两者.因此,在这种情况下,C++/CLI成为一种非常理想的方法.


Joh*_*ren 5

将P / Invoke视为平台调用,您是在调用Win32 API这样对P / Invoke非常友好的东西,还是需要为非托管库提供.NET绑定?

由于包装器通常很薄,因此C ++ / CLI包装器不需要您特别了解C ++ / CLI。您需要了解的内容可以在语言规范中找到,它是一个包含大量示例的广泛文档。P / Invoke在较小的已建立好的现有库中具有更好的功能,但是如果调用该库的接口发生更改,则会遇到问题。使用C ++ / CLI,您仍然可以在C ++ / CLI项目中拥有一个公共的托管接口,该接口公开了托管代码,并以这种方式更轻松地处理了对C API的更改。

如果您想摆脱多余的DLL,可以随时尝试使用ILMerge,但是我不确定它是否能够处理混合程序集(显然不是),但是看起来可以同时链接托管和非托管* .obj文件。使用这样的PlatformSDK链接器:

cl.exe /MD /c /clr Unmanaged.cpp
csc.exe /target:module /addmodule:*.obj Managed.cs
link.exe /DLL /LTCG /NOENTRY /CLRIMAGETYPE:IJW *.obj Managed.netmodule
Run Code Online (Sandbox Code Playgroud)