本文介绍了Silverlight中的Marshal.PtrToStructure的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到了Silverlight 5作业,但是半途而废.让我解释一下.

I got a Silverlight 5 assignment,but I struck in half way.Let me explain.

我的代码在Windows窗体(.Net框架4)中运行良好

My Code which works good in Windows Form (.Net framework 4)

[DllImport("LiteSDK.dll",
            CharSet = CharSet.Ansi,
            EntryPoint = "GetAllUserInfo")]
        public static extern int GetAllUserInfo(int handle, IntPtr userHdr, ref int numOfUser);

    public struct BS2UserHdr
{
public enum ENUM
{
DS_MAX_NAME_LEN = 48,
DS_MAX_PASSWORD_LEN = 16,
DS_MIN_PASSWORD_LEN = 4,

DS_TEMPLATE_SIZE = 384,
DS_FACE_TEMPLATE_SIZE = 2284,

MAX_FINGER = 10,
MAX_FINGER_TEMPLATE = 20,
MAX_FACE = 5,
MAX_FACE_TEPLATE = 5,

USER_ADMIN = 1,
USER_NORMAL = 0,
};

public uint ID;

public ushort headerVersion;
public ushort adminLevel;
public ushort securityLevel;
public ushort statusMask;
public uint accessGroupMask;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public ushort[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public ushort[] department;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public ushort[] password;

public ushort numOfFinger;
public ushort numOfFace;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] duress;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] fingerType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] reserved1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public uint[] fingerChecksum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public uint[] faceChecksum;

public ushort authMode;
public byte bypassCard;
public byte disabled;

public uint cardID;   //card ID
public uint customID; //card Custom ID

public uint startDateTime;
public uint expireDateTime;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public uint[] reserved2;

};

int m_NumOfUser=5;

LiteSDK.BS2UserHdr[] userHdr = new LiteSDK.BS2UserHdr[m_NumOfUser];

IntPtr userInfo = Marshal.AllocHGlobal(m_NumOfUser * Marshal.SizeOf(typeof(LiteSDK.BS2UserHdr)));
int  result = LiteSDK.GetAllUserInfo(2134, userInfo, ref m_NumOfUser);

for (int i = 0; i < m_NumOfUser; i++)
    {
        userHdr[i] = (LiteSDK.BS2UserHdr)Marshal.PtrToStructure(new IntPtr(userInfo.ToInt32() + i * Marshal.SizeOf(typeof(LiteSDK.BS2UserHdr))), typeof(LiteSDK.BS2UserHdr));
        ListViewItem userItem = userList.Items.Add(userHdr[i].ID.ToString());
        userItem.SubItems.Add(userHdr[i].numOfFinger.ToString());
        userItem.SubItems.Add(userHdr[i].cardID.ToString("X"));
    }
Marshal.FreeHGlobal(userInfo);
    }

但是使用Silverlight我不能使用

But using Silverlight I cant use

(LiteSDK.BS2UserHdr)Marshal.PtrToStructure(new IntPtr(userInfo.ToInt32() + i * Marshal.SizeOf(typeof(LiteSDK.BS2UserHdr))), typeof(LiteSDK.BS2UserHdr));

请帮助我解决此问题.我尝试使用GCHandle解决此问题,但无法正常工作.

Please help me to resolve this issue.I tried to use the GCHandle to resolve this issue but not working.

推荐答案

首先用一个类重写ur结构.例如:

First of all rewrite ur struct with a class.eg:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class BS2UserHdr
 {
  public uint ID { get; set; }
  public ushort headerVersion { get; set; }..........

然后创建该类的实例

BS2UserHdr clsTest= new BS2UserHdr();
Marshal.PtrToStructure(new IntPtr(userInfo.ToInt32() + i *     Marshal.SizeOf(typeof(LiteSDK.BS2UserHdr)), clsTest);

现在您可以在clsTest中看到这些值.

Now u can see the values in clsTest.

和Marshal.AllocHGlobal在SL中不起作用,您需要实现

and Marshal.AllocHGlobal will not work in SL,you need to implement

internal static IntPtr AllocHGlobal(int size)
        {
            IntPtr hGlobal = LocalAlloc(LPTR, size);
            if (hGlobal == IntPtr.Zero)
            {
                throw new OutOfMemoryException("Unmanaged memory was not allocated.");
            }
            return hGlobal;
        }

克服这一点.

这篇关于Silverlight中的Marshal.PtrToStructure的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 08:36