C#面试题更新 2026-08-05

请阐述在 .NET 平台下,通过 P/Invoke 机制调用非托管代码的具体步骤与关键注意事项。

风险判断技术原理C#.NET

考察说明

考察对 P/Invoke 工作原理及互操作边缘情况的理解。

回答思路

  1. 【回答框架 1】P/Invoke 是 .NET 提供的平台调用服务,允许托管代码调用非托管动态链接库(如 Win32 API、C/C++ Dll)。核心是 DllImport 特性,通过静态 extern 方法声明。
  2. 【回答框架 2】关键步骤:本机函数的 DllImport 声明,包括库名、入口点、调用约定(CallingConvention)、字符集(CharSet)和 SetLastError。
  3. 【回答框架 3】数据类型映射:需对应非托管类型,如 C 的 int 对应 System.Int32,指针对应 IntPtr,字符串考虑 CharSet 和 Encoding。
  4. 【回答框架 4】内存管理:若函数分配内存返回,需在托管侧释放,或使用 Marshal 类操作,如 AllocHGlobal、FreeHGlobal;对于结构体,注意布局(LayoutKind.Sequential)和大小。
  5. 【回答框架 5】错误处理:利用 SetLastError 和 Marshal.GetLastWin32Error 获取错误代码;异常需包装为托管异常。
  6. 【关键点 1】DllImport 特性是入口,需指定库名和正确的入口点。
  7. 【关键点 2】数据类型和内存布局必须精确匹配,否则可能导致数据损坏或崩溃。
  8. 【关键点 3】调用约定(cdecl 与 stdcall)不一致会导致栈不平衡,引发异常。
  9. 【关键点 4】及时释放非托管内存,避免内存泄漏。
  10. 【易错点 1】字符集(CharSet)设置不当会导致字符串编码错误(如 ANSI vs Unicode)。
  11. 【易错点 2】结构体布局(如对齐)可能因编译器而不同,需显式指定。
  12. 【易错点 3】回调函数需用委托并防止 GC 回收,否则可能访问已释放的内存。