MarshalAs(UnmanagedType.U4)

本文详细介绍了C#中MarshalAsAttribute特性如何用于在托管与非托管代码间转换数据,特别是如何使用UnmanagedType.U4进行封送处理。通过示例展示了[MarshalAs(UnmanagedType.U4)]的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MarshalAs:指示如何在托管代码和非托管代码之间封送数据。

简单点说,托管代码是一microsoft的 中间语言,他主要的作用是在.NET FRAMEWORK的CLR执行代码前去编译 源代码,也就是说托管代码充当着翻译的作用,源代码在运行时分为两个阶段:
1. 源代码编译为托管代码;(所以源代码可以有很多种,如VB,C#,J#)
2.托管代码编译为microsoft系统的.net平台专用文件(如类库、 可执行文件等)。

使用方法:

[MarshalAs(UnmanagedType unmanagedType, 命名参数)]

实际上相当于构造一个MarshalAsAttribute类的对象


UnmanagedType 枚举:指定如何将参数或字段封送到非托管代码。



成员名称 说明
由 .NET Compact Framework 支持 AnsiBStr 长度前缀为单字节的 ANSI 字符串。可以在 String 数据类型上使用此成员。 
由 .NET Compact Framework 支持 AsAny 一个动态类型,将在运行时确定对象的类型,并将该对象作为所确定的类型进行封送处理。仅对平台调用方法有效。 
由 .NET Compact Framework 支持 Bool 4 字节布尔值(true != 0、false = 0)。这是 Win32 BOOL 类型。 
由 .NET Compact Framework 支持 BStr 长度前缀为双字节的 Unicode 字符串。可以在 String 数据类型上使用此成员(它是 COM 中的默认字符串)。 
由 .NET Compact Framework 支持 ByValArray 当 
如果你不想使用UnmanagedExports库,而是想直接编写PInvoke代码来调用kernel32.dll中的ReadPrivateProfileSectionEx函数,你需要了解以下几个关键步骤。请注意,这个过程通常用于底层编程,对于C#开发者来说可能会有些复杂。 1. **包含头文件**: 首先,你需要在项目中引用`System.Runtime.InteropServices`命名空间,以及导入`kernel32.h`头文件: ```csharp using System.Runtime.InteropServices; ``` 2. **声明结构体和函数原型**: kernel32.dll中的ReadPrivateProfileSectionEx函数接受几个参数,包括文件路径、section名称、缓冲区大小等。你需要创建一个结构体来匹配它的输入和输出参数: ```csharp [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct ProfileEntry { public int Length; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)] public string Key; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)] public string Value; } [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool ReadPrivateProfileSectionEx( [MarshalAs(UnmanagedType.LPStr)] string lpFileName, [MarshalAs(UnmanagedType.LPStr)] string lpSectionName, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] ProfileEntry[] lpBuffer, int nSize, [MarshalAs(UnmanagedType.LPStr)] string lpDefaultPath, [MarshalAs(UnmanagedType.U4)] int nOptions, StringBuilder lpErrorBuffer); ``` 3. **处理错误**: 函数可能返回错误信息,所以你需要捕获并处理`lastError`: ```csharp const int ERROR_INSUFFICIENT_BUFFER = 78; // ...其他代码... int requiredBufferSize = 0; ProfileEntry[] buffer = new ProfileEntry[5]; // 初始缓冲区大小 while (true) { if (!ReadPrivateProfileSectionEx(fileName, section, buffer, requiredBufferSize, defaultPath, 0, null)) { if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER) { requiredBufferSize = Marshal.SizeOf(typeof(ProfileEntry)) * buffer.Length; if (requiredBufferSize > 1024) // 你可以选择更大的容量,防止无限循环 { break; } else { buffer = new ProfileEntry[Math.Min(1024, requiredBufferSize)]; } } else { // 错误处理... break; } } else { // 成功读取,处理lpBuffer foreach (var entry in buffer) { // 处理Key和Value } break; } } ``` 4. **清理工作**: 如果有需要,记得释放`lpBuffer`所占用的内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值