【发布时间】:2011-06-15 17:38:36
【问题描述】:
我想用标准的、独立于平台的 C++ 编写一个算法库。
然后我可以采用相同的 C++ 代码并将其编译为 .NET,以便 C# 应用程序可以使用该库吗? 如果没有,实现这种互操作的最简单方法是什么?
【问题讨论】:
标签: .net visual-c++ c++-cli interop managed-c++
我想用标准的、独立于平台的 C++ 编写一个算法库。
然后我可以采用相同的 C++ 代码并将其编译为 .NET,以便 C# 应用程序可以使用该库吗? 如果没有,实现这种互操作的最简单方法是什么?
【问题讨论】:
标签: .net visual-c++ c++-cli interop managed-c++
您不能直接在 C# 和标准 C++ 之间进行接口。但是,您可以在 C++/CLI 包装器中使用您的 C++ 库,这使得该功能在 .NET 托管代码(以及 C#)中可用。
只需将包装器编写为 C++/CLI 库,它公开一个 .NET API 并包含标准 C++ 库中的代码(但不幸的是,据我所知,这不能静态链接)。
【讨论】:
您可以通过三种方式公开您的库,以便从托管代码中轻松调用:
public ref class 的 C++/CLI 包装器 - C# 代码将调用此类的方法,而后者将调用您的库的本机方法第三个,COM,我只是为了完整起见。这不会是我的第一选择。或者我的第三个。 COM 组件是否存在是一回事,为此编写它是另一回事。
在前两个之间,还有谁可以使用这个库是一个问题。如果 C# 代码是唯一使用它的代码,那就做你喜欢的。但是例如,您可能有 15 或 20 个设置各种属性的本机方法,然后是执行实际工作的 go 或 execute 方法。因为托管本机互操作是有成本的,所以我会告诉您编写一个 C++/CLI 函数,它接受 20 个参数,调用各种本机函数,然后调用 go 或 execute。这为您提供了一个更厚实的界面而不是繁琐的界面,并降低了您的互操作成本。
【讨论】:
您可以使用 pinvoke 从任何 .NET 语言调用本机 C/C++ 库。这是来自MSDN 的快速教程。您还可以在 C++ 中创建一个 COM dll,您可以使用 COM Interop 从 C# 中直接引用它。除非您需要 COM 的优势,否则 pinvoke 是一条更容易走的路。
当然,正如 Konrad 所说,您使用托管 C++ 解决方案包装 C++ dll。
例如,查看http://www.pinvoke.net/ 以获取有关如何从 C# 调用 win32 api 的示例。
从上面的 MSDN 链接(根据下面的评论修改):
using System;
using System.Runtime.InteropServices;
class PlatformInvokeTest
{
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int puts(
[MarshalAs(UnmanagedType.LPStr)]
string m);
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int _flushall();
public static void Main()
{
puts("Hello World!");
_flushall();
}
}
【讨论】:
#include <vector> 并从 C# 中破解。
puts 和 _flushall 使用 __cdecl 调用约定导出,但 DllImport 属性使用 __stdcall,除非您另外指定。 (我知道该错误是从您链接到的 MSDN 页面复制的,但您也可以在 IMO 此处修复它。)
__cdecl 和 .NET P/Invoke 的默认值是 __stdcall,鉴于双方均未指定任何内容,因此必须使用默认值。