3

我实际上有两个未损坏的 c++ 库,其中一个使用了另一个。两者都很大,所以重写不是我的选择。

我读了一些关于创建一个包含非托管代码的托管 c++ 库的内容。但我真的不知道如何开始,以及如何将所有这些东西结合到一个项目中......

是否有任何分步指南或易于理解的示例来说明如何执行此操作?

TIA

4

5 回答 5

3

您可能会考虑使用 ATL 为您的 C++ 代码编写一个 COM 包装器。我在一篇博文中展示了如何做到这一点。这就是微软公开他们用 C++ 编写的功能(例如 Windows 7 库功能)的方式。COM 很容易被 .NET/C# 使用(参见这篇文章)。如果你走这条路,如果你不需要与其他人共享你的包装器,你可能会考虑注册免费的 COM 。

于 2009-04-27T23:06:25.633 回答
1

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

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

  1. 使用SWIG为您的 C++ 类自动生成 C# PInvoke 包装器。这种工作,但只有当你需要暴露很多类和成员时才真正值得。根据我的经验,自动生成的代码仍然需要手动进行一些调整。

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

于 2009-04-24T08:47:07.580 回答
1

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

于 2009-04-24T08:53:33.087 回答
1

您有两种选择,一种称为 ijw “它可以正常工作”,您可以在其中编写托管 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++,但我不记得我是怎么想的了。

于 2009-04-27T22:56:39.027 回答
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++ 服务库。

于 2009-04-24T08:51:26.993 回答