C#系统编程:轻松入门无痛苦

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C#系统编程:当高级语言遇上底层硬件

\n\n

当听到“系统编程”这个词时,脑海中通常会浮现出留着胡须的专家们,用C或汇编语言编写代码,终端上满是绿色文字。而C#——它只是“用于业务应用程序”、“用于Windows Forms”和“给不想操心指针的人”的语言。剧透:这是误解。

\n\n

实际上,C#是系统程序员的一把瑞士军刀,既能快速、安全地编写代码,又能在必要时深入非托管内存的核心。在本文中,我们将探讨C#如何解决实际的系统任务:从进程管理到通过WinAPI直接访问内存。是的,代码示例必不可少——没有它们可不行。

\n\n

为什么C#不仅仅是“业务玩具”?

\n\n

用C#进行系统编程并非矛盾。.NET平台(尤其是.NET 5+)为开发者提供了独特的组合:接近原生代码的性能,以及高级语言的便利性。您可以编写驱动程序、管理进程、手动分配内存,同时不必为资源管理而抓狂。

\n\n

使C#适用于系统编程的关键特性:

\n
    \n
  • Unsafe代码和指针——是的,在C#中可以直接操作地址,就像在C++中一样。
  • \n
  • P/Invoke——调用原生库(WinAPI、libc、驱动程序)中的任何函数。
  • \n
  • Span和Memory——安全地操作连续内存块,无需额外分配。
  • \n
  • Native AOT——编译为原生代码,无需JIT和CLR。
  • \n
  • 与C/C++互操作——将C#嵌入现有的系统项目中。
  • \n
\n\n

如果您认为C#只适用于Web和数据库,那就准备好大吃一惊吧。

\n\n

Unsafe代码:玩火,但可控

\n\n

C#中的关键字unsafe就像核导弹上的红色按钮。按下它,您就可以做任何事情:解引用指针、操作固定对象、分配栈内存。但责任也绝对重大。

\n\n

假设我们需要快速复制一个字节数组,绕过边界检查。在安全代码中,我们会使用Array.Copy,但如果我们正在编写一个与驱动程序交互的系统工具,每一微秒都至关重要。

\n\n
using System;\n\nunsafe class MemoryCopy\n{\n    public static void FastCopy(byte[] source, byte[] dest, int length)\n    {\n        fixed (byte* pSrc = source, pDst = dest)\n        {\n            byte* ps = pSrc;\n            byte* pd = pDst;\n            for (int i = 0; i < length; i++)\n                *pd++ = *ps++;\n        }\n    }\n}
\n\n

这里我们使用fixed来“固定”托管数组在内存中,防止垃圾回收器在复制过程中移动它们。结果是复制速度接近C语言的memcpy。当然,对于日常任务来说这有些过度,但对于C#系统编程来说,这是必备技能。

\n\n

何时使用unsafe是合理的?

\n
    \n
  • 在原始字节级别处理网络数据包。
  • \n
  • 通过DMA与硬件交互。
  • \n
  • 实现自定义内存分配器。
  • \n
  • 优化关键代码段(例如,处理摄像头视频)。
  • \n
\n\n

P/Invoke和WinAPI:C#叩击内核之门

\n\n

真正的系统编程离不开调用原生函数。C#为此提供了P/Invoke(平台调用服务)机制。想要获取进程列表、管理窗口或读取其他进程的内存?没问题。

\n\n

来看一个经典示例——通过WinAPI函数CreateToolhelp32Snapshot获取正在运行的进程列表。

\n\n
using System;\nu                

博客

书籍推荐