互操作基础(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 的作用
回顾
回顾:使用 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 反馈 — 无需本地设置。
此课程中的所有课时
- C# 脚本(dotnet script)、代码片段与 REPL
- 互操作基础(P/Invoke)速览
- CLI 易用性