我读了一些关于创建托管c ++库的东西,它围绕非托管代码。但我不知道如何开始,以及如何在一个项目中结合所有这些东西......
是否有任何分步指南或如何做到这一点的易于理解的例子?
TIA
答案 0 :(得分:3)
您可以考虑使用ATL为C ++代码编写COM包装器。我将在blog post中展示如何执行此操作。这就是Microsoft公开他们用C ++编写的功能的方式(例如Windows 7库功能)。 COM很容易被.NET / C#使用(参见this post)。如果你走这条路线,如果你不需要与他人分享你的包装,你可以考虑registration free COM。
答案 1 :(得分:1)
我认为这取决于您实际需要公开多少库功能。
我不知道创建托管C ++包装器,但我个人使用了另外两种方法来解决这个问题:
使用SWIG为您的C ++类自动生成C#PInvoke包装器。这种工作,但如果你需要公开一个很多的类和成员,那真的是值得的。根据我的经验,自动生成的代码仍然需要手动调整。
只为您需要的功能编写非托管C包装器,从DLL导出它们,并手动编写需要导入C#的几个PInvoke包装器。我发现在某些情况下这更合适,例如有一个大型的C ++类库可以执行不同类型的图像文件转换,但您真正想要公开的只是一个函数DoTheConversion(LPWSTR inputFile)
。我的C#程序不需要知道底层类库的所有复杂性。
答案 2 :(得分:1)
您可以在同一个项目中编写托管和非托管C ++。因此,您可以在Managed C ++中编写一个包装器来调用您的本机c ++类等。然后在C#中,您的托管C ++类将像任何其他.net引用一样出现。在这种情况下无需使用P / Invoke。
答案 3 :(得分: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 ++,但我不记得我对它的看法。
答案 4 :(得分:0)
阅读其中一些文章可能是一个开始 - 这是一个相当广泛的主题,而且没有“完美”的方法来做到这一点:
http://www.ondotnet.com/pub/a/dotnet/2004/03/29/mcpp_part3.html http://www.codeguru.com/cpp/cpp/cpp_managed/interop/article.php/c6867
这些方法都没有使用p / invoke,这是我们在我需要连接一个疯狂的旧c ++服务库的项目中使用的方法。