在C#中,System.Runtime.InteropServices
命名空间提供了一个集合的类、接口和结构,用于在托管代码(如C#)和非托管代码(如C/C++、COM组件)之间进行互操作。这些工具可以帮助开发者在C#程序中调用和操作非托管代码,使得可以利用现有的非托管代码库和API。
以下是一些常见的用途和功能:
-
调用非托管代码:
DllImport
属性:用于声明和调用非托管的DLL函数。通过这个属性,C#代码可以调用C/C++编写的动态链接库中的函数。
[DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int MessageBox(IntPtr hWnd, String text, String caption, int options);
-
COM互操作:
Marshal
类:提供了一系列方法,用于在托管和非托管代码之间进行数据的转换和内存的分配、释放。ComImport
属性:用于标记一个接口或类,这样可以从COM库中导入并使用。
[ComImport, Guid("00000000-0000-0000-C000-000000000046")] public interface IUnknown { // Interface definition }
-
内存管理:
Marshal.AllocHGlobal
和Marshal.FreeHGlobal
:用于在非托管内存中分配和释放内存。
IntPtr pnt = Marshal.AllocHGlobal(size); Marshal.FreeHGlobal(pnt);
-
处理结构和指针:
StructLayout
属性:控制托管结构在内存中的布局,确保它与非托管代码预期的布局一致。
[StructLayout(LayoutKind.Sequential)] public struct MyStruct { public int integer; public float floatingPoint; }
-
异常处理:
Marshal.ThrowExceptionForHR
:根据HRESULT代码抛出相应的托管异常。
int hr = SomeUnmanagedFunction(); Marshal.ThrowExceptionForHR(hr);
-
其他互操作功能:
Marshal.GetLastWin32Error
:获取调用非托管函数后最后的错误代码。GCHandle
结构:提供了一种方式来在托管和非托管代码之间传递对象引用。
通过这些工具和功能,System.Runtime.InteropServices
命名空间大大扩展了C#的应用场景,使得它能够更灵活地与现有的非托管代码库进行交互。