将非托管的C++类库暴露给C#

3

我其实有两个未受损的C++库,其中一个利用了另一个库。由于这两个库都相当大,因此重写它们对我来说不是一个选项。

我阅读了一些关于创建包装未管理代码的托管C++库的内容。但我真的不知道如何开始,并且如何在一个项目中组合所有这些内容...

是否有任何逐步指南或易于理解的好例子可以帮助我完成这个任务?

TIA


1
已经在这里回答过了 http://stackoverflow.com/questions/761930/getting-object-functionallity-out-of-c-code-in-c/762012#762012,以及其他很多帖子;这是最近非常常见的问题。 - Not Sure
5个回答

3
你可以考虑使用ATL为你的C++代码编写一个COM包装器。我在博客文章中展示了如何做到这一点。这是微软使用C++暴露功能的方式(例如Windows 7库功能)。.NET/C#很容易使用COM(参见此帖子)。如果您选择这条路线,如果您不需要与其他人共享您的包装器,您可以考虑无需注册的COM

1

你有两个选项,一个叫做ijw "it just works",你可以编写托管的C++代码并调用非托管的C++代码。另一个选项需要使用pinvoke。

如果你使用pinvoke,你会得到类似这样的代码:

C#

somefunction("str1", "str2", "str3", "str4"); 

[DllImport(@"myproj.dll", EntryPoint = "somefunction")]
public static extern IntPtr SomeFunction([MarshalAs(UnmanagedType.LPWStr)]string jarg1, [MarshalAs(UnmanagedType.LPWStr)]string jarg2, [MarshalAs(UnmanagedType.LPWStr)]string jarg3, [MarshalAs(UnmanagedType.LPWStr)]string jarg4);

c++

extern "C" __declspec(dllexport) void* __stdcall somefunction(wchar_t * jarg1, wchar_t * jarg2, wchar_t * jarg3, wchar_t * jarg4) 
{
//do some stuff with strings
}

如果您使用SWIG,SWIG将尝试自动生成上述代码,但它是一个严格的主人。

我曾经使用过托管C++,但我不太记得我当时的想法了。


1

我认为这取决于你需要公开多少库功能。

我不知道如何创建托管的C++包装器,但我个人使用了另外两种方法来解决这个问题:

  1. 使用SWIG自动生成C# PInvoke包装器以公开你的C++类。这种方法有点可行,但只有在你需要公开很多类和成员时才值得尝试。根据我的经验,自动生成的代码仍然需要手动调整。

  2. 为你所需的功能编写未管理的C包装器,从DLL中导出它们,并手动编写几个PInvoke包装器以便在C#中导入。我发现在某些情况下这更加合适,例如有一个大型的C++类库,可以执行不同类型的图像文件转换,但你真正想公开的只是一个函数DoTheConversion(LPWSTR inputFile)。我的C#程序不需要知道底层类库的所有细节。


1

你可以在同一个项目中编写托管和非托管的C++代码。因此,你可以在托管的C++中编写一个包装器来调用你的本地C++类等。然后在C#中,你的托管C++类将像任何其他.NET引用一样出现。在这种情况下,无需使用P/Invoke。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接