C#中互操作性简介
什么是互操作性
互操作性(Interop)指的是不同的软件能够相互操作和通信的能力。在C#中,我们可以使用互操作性来与其他语言编写的代码进行交互,例如与C++或者VB.NET编写的程序进行交互。使用互操作性可以有效地扩展C#程序的功能和灵活性。
C#中的互操作性
在C#中使用互操作性主要通过Platform Invocation Services(P/Invoke)实现。P/Invoke可以将C#程序中的某些方法调用转换为在托管进程外运行的非托管代码。当然,在使用P/Invoke时我们需要了解第三方非托管代码的函数或者数据结构的定义。通常情况下,我们需要使用DllImport属性来指定要调用的非托管函数的名称和库。
例如下面的代码演示了如何在C#中使用P/Invoke来调用非托管函数MessageBoxA:
using System.Runtime.InteropServices;
class Program
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
static void Main(string[] args)
{
string messageBoxText = "Hello, world!";
string messageBoxCaption = "MessageBox Test";
uint messageBoxType = 0;
MessageBox(IntPtr.Zero, messageBoxText, messageBoxCaption, messageBoxType);
}
}
示例说明
示例一:C#调用C++编写的DLL文件
在这个示例中,我们展示了如何在C#中调用C++编写的DLL文件。我们需要首先使用C++编写一个简单的DLL文件,然后在C#中声明被调用的方法并且通过Platform Invocation Services(P/Invoke)调用该方法。
- 编写C++动态链接库
// MathFuncsDll.h
#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport)
#else
#define MATHFUNCSDLL_API __declspec(dllimport)
#endif
namespace MathFuncs
{
class MyMathFuncs
{
public:
// Returns a + b
static MATHFUNCSDLL_API double Add(double a, double b);
// Returns a - b
static MATHFUNCSDLL_API double Subtract(double a, double b);
// Returns a * b
static MATHFUNCSDLL_API double Multiply(double a, double b);
// Returns a / b
// Throws DivideByZeroException if b is 0
static MATHFUNCSDLL_API double Divide(double a, double b);
};
}
- 生成动态链接库文件
将C++代码编译成动态链接库文件(DLL)。
- 在C#中调用C++动态链接库
使用下面的代码在C#中声明被调用的方法,然后通过Platform Invocation Services来调用该方法。这个例子展示了如何在C#中调用一个返回值为double类型的函数。
using System.Runtime.InteropServices;
class Program
{
[DllImport("MathFuncsDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern double Add(double a, double b);
static void Main(string[] args)
{
double a = 10;
double b = 20;
double sum = Add(a, b);
Console.WriteLine("{0} + {1} = {2}", a, b, sum);
}
}
示例二:C#将字符串转换为非托管内存字符数组
在这个示例中,我们展示了如何在C#中将字符串转换为非托管内存字符数组。我们首先在C#中声明了被调用的非托管函数,然后利用Marshal.StringToCoTaskMemAnsi方法将字符串转换为字符数组,最终将字符数组传递给被调用函数。
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("StringManipulationDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void PrintCharArray(IntPtr charArray);
static void Main(string[] args)
{
string text = "Hello, world!";
byte[] charArray = Encoding.ASCII.GetBytes(text);
IntPtr pnt = Marshal.StringToCoTaskMemAnsi(text);
try
{
PrintCharArray(pnt);
}
finally
{
Marshal.FreeCoTaskMem(pnt);
}
}
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#中互操作性简介 - Python技术站