0Pricing
C# Academy · 课时

互操作基础(P/Invoke)速览

使用 P/Invoke 调用本机函数:了解 DllImport 基础、字符串封送、SetLastError,以及简单的 Win32 演示(Sleep、GetTickCount64)。

互操作基础(P/Invoke)速览 是 CoddyKit 上的免费 C# Academy 课时。 这是第 2 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 3 节课。

概念与目标

P/Invoke可以让 C# 调用原生 DLL 中的函数。

  • 使用 DllImport 绑定方法
  • 在需要时选择 CharSet 和 SetLastError
  • 保持签名简单且准确

P/Invoke:Sleep

通过使用 DllImport 声明托管方法来绑定原生函数。

using System;
using System.Runtime.InteropServices;

// Simple P/Invoke call to native Sleep (Windows kernel32)
// Note: This demo may only run on Windows, but it compiles everywhere.
public class Program
{
  [DllImport("kernel32.dll")]
  private static extern void Sleep(uint dwMilliseconds);

  public static void Main(string[] args)
  {
    Console.WriteLine("Sleeping for 200 ms...");
    // Call native function
    Sleep(200);
    Console.WriteLine("Awake!");
  }
}

原生返回值

匹配原生签名:此处返回一个无符号 64 位值。

using System;
using System.Runtime.InteropServices;

// Get system uptime (ms) from native function.
public class Program
{
  [DllImport("kernel32.dll")]
  private static extern ulong GetTickCount64();

  public static void Main(string[] args)
  {
    ulong ms = GetTickCount64();
    Console.WriteLine("Uptime (ms): " + ms);
  }
}

字符串与 CharSet

对于宽字符串 API(“W”版本),使用 CharSet.Unicode。捕获不受支持平台上的运行时错误。

using System;
using System.Runtime.InteropServices;

// Demo: marshaling strings to Unicode with CharSet.Unicode.
// On non-Windows environments this may fail at runtime.
public class Program
{
  [DllImport("user32.dll", CharSet = CharSet.Unicode)]
  private static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);

  public static void Main(string[] args)
  {
    Console.WriteLine("Calling MessageBox (may require Windows GUI)...");
    // 0x00000040 = MB_ICONINFORMATION
    try
    {
      int result = MessageBox(IntPtr.Zero, "Hello from P/Invoke", "Interop", 0x00000040);
      Console.WriteLine("MessageBox returned: " + result);
    }
    catch (Exception ex)
    {
      Console.WriteLine("MessageBox failed at runtime: " + ex.GetType().Name);
    }
  }
}

SetLastError 与类型

错误处理:

  • 对于会设置 GetLastError 的 API,在 DllImport 中添加 SetLastError=true
  • 调用失败后,读取 Marshal.GetLastWin32Error()
  • 优先使用准确的类型:uint 与 int,指针使用 IntPtr

互操作规范

  • 从简单的 API 开始(不包含复杂结构)
  • 对句柄使用 IntPtr;使用正确的原生函数释放句柄
  • 避免在无头环境中调用 GUI
  • 记录平台限制(仅限 Windows 等)

DllImport 的作用

快速检查:在 P/Invoke 中,DllImport 特性有什么作用?

回顾

回顾:使用 DllImport 声明原生调用,仔细匹配类型,为字符串选择 CharSet,并在适用时通过 SetLastError 和 GetLastError 处理错误。

常见问题解答

「互操作基础(P/Invoke)速览」课时是免费的吗?

是的 — 「互操作基础(P/Invoke)速览」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 3 节课。

「互操作基础(P/Invoke)速览」这节课中我会学到什么?

使用 P/Invoke 调用本机函数:了解 DllImport 基础、字符串封送、SetLastError,以及简单的 Win32 演示(Sleep、GetTickCount64)。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C# Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 3 节。

「互操作基础(P/Invoke)速览」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C# Academy 课中编写并运行代码吗?

能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. C# 脚本(dotnet script)、代码片段与 REPL
  2. 互操作基础(P/Invoke)速览
  3. CLI 易用性
← 返回 C# Academy