当前位置: 首页 > news >正文

C# 与 C 类型对照速查表

C# 与 C 类型对照速查表

一、基础数值类型(无符号 / 有符号整数)

C/C++ 原生类型Windows 宏别名占用字节C# 对应类型说明
charCHAR1sbyte / bytechar 有符号;unsigned char = byte
unsigned charUCHAR, BYTE1byteBYTE=unsigned char,0~255
shortSHORT2short16 位有符号
unsigned shortUSHORT, WORD2ushortWORD,0~65535
intINT4int32 位有符号
unsigned intUINT4uint32 位无符号
longLONG4intWindows 下 long 固定 4 字节
unsigned longULONG, DWORD4uintDWORD=ULONG 0~0xFFFFFFFF
long longLONGLONG8long64 位有符号
unsigned long longULONGLONG, DWORDLONG8ulong64 位无符号大容量数值
floatFLOAT4float单精度浮点
doubleDOUBLE8double双精度浮点

特殊常量对照

  • INVALID_FILE_ATTRIBUTES = (DWORD)-1→ C#public const uint INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF;
  • INVALID_HANDLE_VALUE = (HANDLE)-1→ C#IntPtr(-1)

二、句柄、指针类(内核对象 / 内存地址)

C/C++ 类型含义C# 类型使用说明
void*通用指针IntPtr万能指针,存放地址
HANDLE内核对象句柄(文件、线程、进程、事件)IntPtrCreateFile、OpenProcess 返回
HMODULEDLL/EXE 模块句柄IntPtrLoadLibrary 返回
HWND窗口句柄IntPtrFindWindow、MessageBox 窗口参数
HDC绘图设备上下文IntPtrGDI 绘图 API
HBITMAP / HPEN / HBRUSHGDI 资源句柄IntPtr位图、画笔、画刷
HINSTANCE程序实例句柄IntPtr等价 HMODULE
LPVOID / LPCVOID通用读写缓冲区指针IntPtr / byte[]ReadFile/WriteFile 数据缓冲区
LPVOID*指针的指针out IntPtr输出句柄、输出指针

关键规则

  1. 所有句柄统一用IntPtr,不用int/uint(64 位程序地址会溢出);
  2. 无效句柄判断:if (h == IntPtr.Zero || h == (IntPtr)(-1))

三、字符串类型(ANSI / Unicode 宽字符,重点易错)

C/C++ 类型编码C# 入参类型C# 输出参数DllImport CharSet 配置
LPCSTR / LPSTRGBK ANSI 单字节stringStringBuilderCharSet.Ansi
LPCWSTR / LPWSTRUTF16 宽字符(xxxW)stringStringBuilderCharSet.Unicode
TCHAR / LPTSTR自适应stringStringBuilderCharSet.Auto

重点说明

  1. 输入字符串:单纯传入路径 / 文本用string
  2. 输出字符串(API 填充缓冲区)不能用 string,必须StringBuilder; 例:GetModuleFileNameW、GetWindowTextW;
  3. GetProcAddress 函数名参数是 ANSI:[DllImport(..., CharSet.Ansi)]

四、布尔类型

C/C++说明C# 类型注意
BOOLint 底层,TRUE=1,FALSE=0bool / int推荐 bool,非 0 自动 true
BOOLEANBYTE 1 字节布尔byte极少 API 使用

五、函数指针 / 回调(DLL 动态调用、窗口回调)

C 写法

typedef int (WINAPI *MsgBoxPtr)(HWND hWnd, LPCWSTR txt, LPCWSTR cap, UINT type);

C# 对应规则

  1. delegate定义;
  2. 必须加特性[UnmanagedFunctionPointer(CallingConvention.StdCall)]
  3. Windows API 统一StdCall调用约定,漏写会栈崩溃。

表格

C 类型C# 实现
WINAPI 函数指针标记 StdCall 的 delegate
LPVOID lpCallbackIntPtr / delegate

C#

[UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate int DlgMsgBox(IntPtr hWnd, string text, string cap, uint type);

C#

IntPtr pFunc = GetProcAddress(hMod, "MessageBoxW"); DlgMsgBox fn = Marshal.GetDelegateForFunctionPointer<DlgMsgBox>(pFunc);

六、结构体 / 联合体(Windows 常用大结构)

通用映射规则

  1. C# 结构体加[StructLayout(LayoutKind.Sequential)]保持内存顺序;
  2. 有指针 / 句柄成员一律用IntPtr
  3. 字符数组缓冲区用fixed byte[]StringBuilder
C 结构示例C# 处理方案
LARGE_INTEGER(联合体高低位)long(直接用 ulong/long 替代 QuadPart)
OVERLAPPED 异步 IO 结构体自定义 Struct,Sequential 布局
SECURITY_ATTRIBUTES自定义结构体,nLength 必须赋值

LARGE_INTEGER 简化对照(最常用)

C:

typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; }; LONGLONG QuadPart; } LARGE_INTEGER;

C# 直接简化:

// GetFileSizeEx 直接传 out long 替代结构体 [DllImport("kernel32.dll")] public static extern bool GetFileSizeEx(IntPtr hFile, out long lpFileSize);

七、指针输出参数(带 LP 前缀,输出值)

C 原型:BOOL GetXXX(DWORD* outValue);

C 参数C# 修饰符示例
LPDWORD / DWORD*out uintout uint dwOut
LPULONGLONG / ULONGLONG*out ulongout ulong llOut
LPHANDLE / HANDLE*out IntPtrout IntPtr hOut
LPBOOL / BOOL*out boolout bool bRet

c

BOOL GetDiskFreeSpaceEx(LPCWSTR path, ULARGE_INTEGER* avail, ULARGE_INTEGER* total, ULARGE_INTEGER* free);

C#:

[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool GetDiskFreeSpaceEx(string path, out long avail, out long total, out long free);

八、调用约定对照表

C 宏调用约定C# 委托标记使用场景
WINAPI / __stdcallStdCallCallingConvention.StdCall所有 Windows 系统 API(默认)
__cdeclCdeclCallingConvention.CdeclC 标准库、第三方自定义 DLL

九、高频易错坑总结

  1. DWORD 不要用 int:无符号数值,超过 21 亿会溢出;统一 uint;
  2. 句柄禁止用 int/long:64 位程序地址超 32 位,必须 IntPtr;
  3. 输出字符串不用 string,只用 StringBuilder;
  4. 宽字符 API 统一CharSet.Unicode,解决中文路径乱码;
  5. 函数指针委托必须指定 StdCall,否则程序直接崩溃;
  6. 结构体不加 Sequential 会内存对齐错乱,读取数据错误;
  7. LoadLibrary / CreateFile 路径传中文,必须 W 版本 + Unicode 字符集。

C# 使用[DllImport]引入原生 Win32 API,分宽字符 W 版本(推荐,支持中文路径)

一、基础知识点

  1. [DllImport("kernel32.dll")]:从系统内核库导入 API
  2. CharSet = CharSet.Unicode= 调用 xxxW 宽字符版本,避免中文乱码
  3. StringBuilder作为输出字符串缓冲区(C# string 不可修改,不能当输出参数)
  4. IntPtr对应 C/C++ 里HMODULE / HANDLE / void*

1. GetModuleFileNameW C# 实现(获取程序自身路径)

using System; using System.Text; using System.Runtime.InteropServices; class Win32Helper { // 导入API [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern uint GetModuleFileNameW( IntPtr hModule, // NULL=0 取当前EXE StringBuilder lpFilename, uint nSize ); static void Main() { StringBuilder sbPath = new StringBuilder(1024); uint ret = GetModuleFileNameW(IntPtr.Zero, sbPath, (uint)sbPath.Capacity); if (ret > 0) { Console.WriteLine("程序完整路径:" + sbPath.ToString()); // 截取目录(去掉exe文件名) string dir = System.IO.Path.GetDirectoryName(sbPath.ToString()); Console.WriteLine("程序目录:" + dir); } else { Console.WriteLine("获取失败"); } Console.ReadKey(); } }

2. LoadLibraryW + GetProcAddress + FreeLibrary C# 动态调用 DLL

模拟 C 里动态加载 user32 调用 MessageBoxW

using System; using System.Runtime.InteropServices; class DllInvokeDemo { // 1. 加载释放DLL [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern IntPtr LoadLibraryW(string lpLibFileName); [DllImport("kernel32.dll", CharSet = CharSet.Ansi)] // 函数名是ASCII public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); [DllImport("kernel32.dll")] public static extern bool FreeLibrary(IntPtr hModule); // 2. 定义MessageBoxW委托(对应C函数指针) [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate int DlgMsgBox(IntPtr hWnd, string text, string caption, uint type); static void Main() { // 加载user32.dll IntPtr hUser32 = LoadLibraryW("user32.dll"); if (hUser32 == IntPtr.Zero) { Console.WriteLine("加载DLL失败"); return; } // 获取MessageBoxW地址 IntPtr pMsgBox = GetProcAddress(hUser32, "MessageBoxW"); if (pMsgBox == IntPtr.Zero) { FreeLibrary(hUser32); return; } // 转为委托调用 DlgMsgBox msgBox = Marshal.GetDelegateForFunctionPointer<DlgMsgBox>(pMsgBox); msgBox(IntPtr.Zero, "C#调用Win32 API弹窗", "提示", 0); // 释放库 FreeLibrary(hUser32); Console.ReadKey(); } }

3. 常用配套 API 补充(GetFileAttributesW / INVALID_FILE_ATTRIBUTES)

public const uint INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF; [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern uint GetFileAttributesW(string lpFileName); // 使用 uint attr = GetFileAttributesW(@"D:\test.txt"); if (attr == INVALID_FILE_ATTRIBUTES) { Console.WriteLine("文件不存在/无法访问"); } else { bool isHidden = (attr & 2) != 0; // FILE_ATTRIBUTE_HIDDEN = 2 Console.WriteLine("是否隐藏:" + isHidden); }

关键注意事项

  1. CharSet.Unicode 必须加不加默认 Ansi,中文路径、中文参数会乱码。
  2. 输出字符串不能用string,必须StringBuilder原生 API 要改写缓冲区,string 是只读。
  3. 函数名参数GetProcAddress传 ANSI 字符串 导出函数名字符串固定 ASCII,所以[DllImport]CharSet.Ansi
  4. 委托必须标记[UnmanagedFunctionPointer(CallingConvention.StdCall)]Windows API 统一__stdcall 调用约定,漏写会栈失衡崩溃。
  5. 资源释放LoadLibrary后必须FreeLibrary,避免内存泄漏。

4. C# 与 C 类型对照速查表

C/C++ 类型C# 对应类型
HMODULE / HANDLEIntPtr
DWORDuint
LPCWSTR / LPWSTRstring / StringBuilder
WINAPI 函数指针delegate + Marshal.GetDelegateForFunctionPointer
BOOLbool
http://www.cnnetsun.cn/news/3002020.html

相关文章:

  • 中文NLP的语义断层:3步解决全词掩码技术实践
  • 低压电工- 光电传感器(Photoelectric Sensor)
  • 用 Vercel Eve 的 Subagent 和 Skill 搭建 Agent Team
  • 客流增35%驻留延40%:贵州安顺古城美陈设计核心技巧-肆墨设计
  • 天津翻译机构 法语网站本地化清单
  • PVE Tools:Proxmox VE终极管理工具箱,让虚拟化管理变得简单高效
  • 2026年【江苏“信息与未来”编程思维】真题及题解(T2:快递无人机)
  • GitHub爆火Skill三巨头实测:选错直接让AI代码精神分裂
  • 遗传算法实战:编码策略、适应度设计与早熟诊断
  • NanaZip完整指南:为什么这款Windows压缩工具值得你立即尝试
  • 终极指南:如何在Windows 11 LTSC系统中轻松安装Microsoft Store应用商店
  • TestSprite 全自动化 AI Web 测试详解——从原理到测试报告完整实战指南
  • Boss直聘批量投递工具:3步让你每天多投50份简历
  • 权威测评:2026年不容错过的专业AI论文软件
  • 回归模型评估指标实战指南:从面试陷阱到工业级KPI诊断
  • 3分钟掌握:B站视频下载工具的核心技术与实战指南
  • 5分钟掌握跨平台资源下载工具:你的智能资源嗅探器终极指南
  • 为什么你的浏览器需要一个本地视频下载扩展?
  • EdgeRemover:Windows系统上彻底告别微软Edge的终极解决方案
  • 算法竞赛实战复盘:从读题策略到代码模板的系统性备赛方法
  • 基于Pytest+Requests+Allure的接口自动化测试框架实战指南
  • 多维聚合实战:维度建模、度量聚合与数据变形三步法
  • Claude语义压缩层蒸发:架构级黑箱化与可控性重构指南
  • 魔兽争霸3性能重生:如何用开源工具让经典游戏在现代硬件上焕发新生
  • KMS_VL_ALL_AIO:5分钟搞定Windows和Office永久激活终极方案
  • 从经典到粘性解:非一致椭圆方程Harnack不等式理论与数值实践
  • Prompt Engineering 与 Agent 工作流:从单次调用到自主决策的编排架构
  • 041、继承的正确打开方式:单继承、多重继承、Mixin 模式与钻石问题
  • AI应用安全部署:3步实现环境变量与密钥管理,告别硬编码风险
  • VMware桥接不上网?别重装!资深架构师压箱底的7个诊断命令清单(含Wireshark抓包黄金组合)