Marshal.PtrToStructure 和 String 的问题

Posted

技术标签:

【中文标题】Marshal.PtrToStructure 和 String 的问题【英文标题】:Problems with Marshal.PtrToStructure and String 【发布时间】:2011-06-14 14:07:37 【问题描述】:

我有以下课程

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public class xy11Dataset : SZLDataset

    public short Index  get; set; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    private string _mlfB;
    public string MlfB
    
        get  return _mlfB; 
        set  _mlfB = value; 
    

    public UInt16 BGTyp  get; set; 

    public UInt16 Ausbg1  get; set; 

    public UInt16 Ausbg2  get; set; 

我用以下代码填充它:

byte[] objBuffer = new byte[retVal.Size];
Array.Copy(buffer, (n*retVal.Size) + 8, objBuffer, 0, retVal.Size);
GCHandle handle = GCHandle.Alloc(objBuffer, GCHandleType.Pinned);
datsets.Add((xy11Dataset)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(xy11Dataset)));
handle.Free();

我在位置 2 的 objBuffer 中有值(应该是字符串的开头),但字符串保持为空!

【问题讨论】:

【参考方案1】:

您需要在这里放弃使用自动属性。它们生成一个与属性连续的私有支持字段,它被添加到末尾。您可以使用 ildasm.exe 查看它们,它们的名称类似于 <Index>k_Backingfield。你需要让这个表达式返回正确的值:

        int offs = (int)Marshal.OffsetOf(typeof(xy11Dataset), "_mlfB");

我看不到 SZLDataSet 包含的内容,但没有它,它现在返回 0。不正确,你想要 2。最好的办法是声明一个带有公共字段的结构,其布局与缓冲区中的数据完全匹配。从值初始化类对象。

【讨论】:

不是在声明属性的地方生成自动属性支持字段吗?无论如何,建议避免使用自动属性;提供对字段顺序的更多控制。 与属性连续”,我尽可能地明确了。

以上是关于Marshal.PtrToStructure 和 String 的问题的主要内容,如果未能解决你的问题,请参考以下文章

PtrToStructure 错误提示:此结构不得为值类,解决办法

求一个异步处理消息的方法

封送包含 char* 成员的非托管结构

如何在 C# 中获取 IntPtr 指针的属性

& 和 && 区别和联系,| 和 || 区别和联系

第三十一节:扫盲并发和并行同步和异步进程和线程阻塞和非阻塞响应和吞吐等