2013-06-26 61 views
0

我得到了一個Silverlight 5的作業,但是我半途而廢。讓我解釋一下。這在Windows窗體做工不錯Silverlight中的Marshal.PtrToStructure

我的代碼(.NET框架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我不能使用

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

請幫我解決這個issue.I試圖用GCHandle解決此問題,但無法正常工作。

+0

你爲什麼使用編組?您只需使用編組與非託管代碼互操作即可。 – shf301

+0

LiteSDK是一個C DLL ... – Christena

+0

好吧 - 爲什麼不能在Silverlight中使用'Marshal.PtrToStructure'?它受到支持(只要您的應用程序以完全信任的方式運行)。 – shf301

回答

0

首先用類重寫ur結構體。 如:

[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值。

和Marshal.AllocHGlobal不會SL工作,你需要實現

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

克服這一點。

+0

感謝Dilip.its的工作。 – Christena