如何使用C#和.NET的C ++库?

我的问题与DLL如何导出C ++类和generics方法(没有C#并行的wrt C ++语言特性)密切相关。

我相信你可以通过引用DLL并使用DLLImport来调用C#中的extern "C"块内的函数。 但是你可以实例化一个模板化的C ++类型吗? 如果C ++类型在C#中不支持那些疯狂的东西怎么办? 是否存在RFC或C#规范的相关部分?

谢谢…

编辑:我现在偶然发现P / Invoke应该是有价值的,但我仍然在寻找关于此的规范或标准。

理所当然的方法是使用托管c ++访问非托管c ++并编译成程序集。

我相信你可以通过引用DLL来调用C#中的extern“C”块内的函数。

错了,您必须使用DllImport或所谓的PInvoke (平台调用)从托管代码调用本机C函数。 引用仅适用于.NET程序集或具有自动生成的interop dll的 COM。

使用C#中的C ++会成为一个真正的噩梦,因为名称会在其他方面被破坏。

如果可以,您可以编译托管C ++ Dll作为包装,以使两个世界相遇。 这样做的ComVisible好处是,您可以将程序集标记为ComVisible ,从而使其可用于大量能够处理COM的工具。

另一种方法是围绕C ++ API编写一个C包装器,这可能是乏味和丑陋的。

编辑:

帮助确定使用哪种方法:

  • 1)你有一个本机C dll
    • 警告:如果您使用托管C ++中的.lib,则dll不会真正动态链接,并且不能通过简单的新版兼容版本替换。
    • 首选:使用任何.NET语言的P / Invoke(可以直接替换)
  • 2)你有一个原生的C ++ DLL
    • 不要使用P / Invoke,这是一个真正的噩梦(因为其他东西的名称损坏)
    • 首选:使用托管C ++构建包装器.NET dll,仅当您的编译器与用于编译本机dll的编译器兼容时才有效。
    • 如果本机DLL是使用可用于托管C ++(编译器C)的编译器(编译器A)的不兼容编译器(编译器A)构建的,那么我建议构建(使用相同的编译器A)围绕本机C ++ dll的C包装器。 然后使用P / Invoke方法使用此包装器C dll,如1)中所述

就C#而言,DLL内部的作用是无关紧要的。 请记住,在实例化模板之前,C ++模板不会生成任何代码。 如果模板只是在DLL头文件中的某个位置定义,则DLL中不会为该模板生成任何代码。 另一方面,如果DLL显式实例化并导出一些模板化类型,那么理论上你可以从C#中调用它们。

你必须克服两个问题。 首先是C ++编译器破坏了他们的方法名称,所以你必须弄清楚PInvoke的正确名称是什么。 第二个问题是没有办法直接在C#中创建CRT对象。 您必须定义一些工厂方法并将其导出。

坦率地说,我觉得这比它的价值更麻烦。 你最好为DLL创建一个C风格的API并从C#调用这些函数。 在内部,函数可以创建和操作相关的C ++对象。