Marshal.PtrToStructure 和 String 的问题

发布于 2024-10-14 03:53:20 字数 874 浏览 3 评论 0原文

我有以下类

[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();

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

I've the following class

[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; }
}

and I fill it with the following code:

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();

I've Values in objBuffer at Position 2 (which should be the start of the string), but the string stays empty!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

指尖微凉心微凉 2024-10-21 03:53:20

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

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

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

You need to give up on using auto properties here. They generate a private backing field that is not sequential with the property, it's added to the end. You can see them with ildasm.exe, they have a name like <Index>k_Backingfield. You need to make this expression return the correct value:

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

I cannot see what SZLDataSet contains but without it this returns 0 right now. Not correct, you'd want 2. Best thing to do is to declare a struct with public fields whose layout is an exact match with the data in the buffer. Initialize the class object from the value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文