【发布时间】:2011-02-12 18:44:05
【问题描述】:
我对托管/非托管互操作性和 COM 概念非常陌生。
我收到了使用 COM Interop 的建议,以便在 C# 中使用我现有的 MFC 代码。但对我来说问题是,我有一个不是有效 COM 组件的 MFC Dll。如何使这个 MFC DLL 具有可在 .NET 中使用的 COM 可访问接口?
【问题讨论】:
标签: c# dll mfc unmanaged com-interop
我对托管/非托管互操作性和 COM 概念非常陌生。
我收到了使用 COM Interop 的建议,以便在 C# 中使用我现有的 MFC 代码。但对我来说问题是,我有一个不是有效 COM 组件的 MFC Dll。如何使这个 MFC DLL 具有可在 .NET 中使用的 COM 可访问接口?
【问题讨论】:
标签: c# dll mfc unmanaged com-interop
来自线程 Loading MFC DLL in C# Windows Application
要从 C# 访问本机代码,您有几个选择。
最直接的是,您可以使用 DllImportAttribute 以 C# 术语描述 DLL 的入口点,以便可以通过 P/Invoke 调用它们。它们看起来像 C# 程序的静态方法。
不太直接,您可以创建一个托管 C++ 程序集,将您的 DLL 包装在一个或多个托管对象中。托管 C++ DLL 可以通过添加引用从 C# 访问(因为它是具有 .dll 扩展名的托管程序集),并且还应该能够通过使用 #include 来访问您的 MFC dll 以包含 MFC dll 的头文件。
第三种选择是将您的 dll 转换为 COM 对象,以便您的 C# 程序可以通过这种方式访问它。
【讨论】:
没有简单的方法可以使 MFC Dll COM 可访问。需要手动编写大量的 COM 代码,制作 COM 包装器。如果您没有以前的 COM 经验,这可能会很困难。 Jacob Seleznev 帖子中的第二个选项看起来不那么痛苦。 C++/CLI 包装器内部链接到现有 MFC dll,并向 C# 客户端公开纯 .NET 接口,看起来是最佳解决方案。
如果 MFC Dll 导出 C 样式接口 (API),而不是类,请使用 PInvoke。
【讨论】:
根据我的经验,我同意@Jacob Seleznev 并补充说,如果您的 MFC DLL 接口主要包含“简单”参数和返回类型,则使用 DLLImportAttribute 很可能是您阻力最小的路径。
编组类型的一个很好的参考是查看它是如何针对非托管 Win32 API 完成的。可以在这里找到: pinvoke.net
我所做的是找到一个具有相似类型的 API 调用,并查看如何在 pinvoke.net 上设置该调用。我不再经常使用它,但几年前它非常有用。
希望这会有所帮助。
【讨论】:
在从托管代码(COM 互操作、P/Invoke 和 IJW 或 C++/CLI 互操作)调用本机代码的三种方法中,COM 互操作是最慢的。如果您现有的本机代码不是 COM 组件的形式,那么它也是最难的,因为那将是第 1 步。
要使用 P/Invoke,您将需要一些 C 风格的函数 (extern C) 继续调用您现有的代码。要使用 IJW 或 C++/CLI 互操作,您将实现一个 public ref 类(在编译的 /clr 文件中),其中包含继续调用现有代码的方法。这取决于您是否觉得更容易。一旦你有了包装器,你可以在 C# 中使用 DllImport 属性在函数的声明中执行 PInvoke,然后像往常一样调用它们。要执行 IJW,您需要添加对包含公共 ref 类的程序集的引用,并像往常一样调用该类的方法。
我的建议是询问您是否想要某种外观模式,在互操作之前放置一些逻辑 - 如果是,请使用 IJW。另外,如果您想控制编组,请转到 IJW。如果没有,那么去 P/Invoke。但无论哪种方式都有效。
【讨论】: