C++结构体:
typedef struct simphonebookentryex_tag {
  DWORD cbSize;
  DWORD dwParams;
  TCHAR lpszAddress[MAX_LENGTH_ADDRESS];
  DWORD dwAddressType;
  DWORD dwNumPlan;
  TCHAR lpszText[MAX_LENGTH_PHONEBOOKENTRYTEXT];
    TCHAR lpszSecondName[MAX_LENGTH_PHONEBOOKENTRYTEXT];
    DWORD dwIndex;
  BOOL fHidden;
    DWORD dwGroupIdCount;
    DWORD rgdwGroupId[MAX_NUM_GROUPS];
   DWORD dwUid;
    DWORD dwAdditionalNumberCount;
   LPSIMPHONEBOOKADDITIONALNUMBER lpAdditionalNumbers;
    DWORD dwEmailCount;
    LPSIMPHONEBOOKEMAILADDRESS lpEmailAddresses;
} SIMPHONEBOOKENTRYEX, *LPSIMPHONEBOOKENTRYEX;typedef struct simphonebookentryex_tag {
  DWORD cbSize;
  DWORD dwParams;
  TCHAR lpszAddress[MAX_LENGTH_PHONEBOOKENTRYTEXT];
} SIMPHONEBOOKEMAILADDRESS, *LPSIMPHONEBOOKEMAILADDRESS;typedef struct simphonebookentryex_tag {
  DWORD cbSize;
  DWORD dwParams;
  TCHAR lpszAddress[MAX_LENGTH_ADDRESS];
    DWORD dwAddressType;
    DWORD dwNumPlan;
  DWORD dwNumId;
} SIMPHONEBOOKADDITIONALNUMBER, *LPSIMPHONEADDITIONALNUMBER;
C++方法:
HRESULT SimWritePhonebookEntryEx(
  HSIM hSim,
  DWORD dwLocation,
  DWORD dwIndex,
  LPSIMPHONEBOOKENTRYEX lpEntries
);
C#转化的数据结构
      public struct SimPhoneBookEntries
      {
          public int cbSize;
          public int dwParams;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
          public string lpszAddress;
          public int dwAddressType;
          public int dwNumPlan;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
          public string lpszText;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
          public string lpszSecondName;
          public int dwIndex;
          public Int32 fHidden;
          public int dwGroupIdCount;
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
          public int rgdwGroupId;
          public int dwUid;
          public int dwAdditionalNumberCount;
          public IntPtr lpAdditionalNumbers;
          public int dwEmailCount;
          public IntPtr lpEmailAddresses;      }      [StructLayout(LayoutKind.Sequential)]
      public struct SimPhoneBookAdditionNumber 
      {
          public uint cbSize;
          public uint dwParams;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
          public string lpszAddress;
          public uint dwAddressType;
          public uint dwNumPlan;
          public uint dwNumId;
      }
      [StructLayout(LayoutKind.Sequential)]
      public struct SimPhoneBookEmailAddress
      {
          public uint cbSize;
          public uint dwParams;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
          public string lpszAddress;
      }
C#包装的方法:
[DllImport("cellcore.dll",CallingConvention= CallingConvention.Winapi,CharSet= CharSet.Unicode)]
public static extern IntPtr SimReadPhonebookEntries(int hSim, int dwLocation, int dwStartIndex, ref int lpdwCount,ref SimPhoneBookEntries enteries, ref int lpdwBufferSize);在C++中此方法返回一个成员是SimPhoneBookEntries的结构体数组,但是在C#中不知道怎么转化让他传出一个结构体数组,按上面的转化提示错误是“NotSupportedException 
此外此程序是在Mobile6的平台上运行,看了Marshal.AllocHGlobal()与Marshal.SizeOf()对compactNet的支持,但是还是发生NotSupportedException 
还请高手给点提示。

解决方案 »

  1.   

    上面的贴错了 c++的方法原型:
    HRESULT SimReadPhonebookEntries(
      HSIM hSim,
      DWORD dwLocation,
      DWORD dwStartIndex,
      LPDWORD lpdwCount,
      LPSIMPHONEBOOKENTRYEX lpEntries,
      LPDWORD lpdwBufferSize
    );
      

  2.   

    [DllImport("cellcore.dll",CallingConvention= CallingConvention.Winapi,CharSet= CharSet.Unicode)] 
    public static extern IntPtr SimReadPhonebookEntries(int hSim, int dwLocation, int dwStartIndex, ref int lpdwCount,ref IntPtr enteries, ref int lpdwBufferSize);   IntPtr p = IntPtr.Zero;
                Marshal.StructureToPtr(typeof(SimPhoneBookEntries), p, false);
      

  3.   

    我不知道你要做什么啊
    有些东西是有函数直接可以由指针获取对象的
    例如
    System.Drawing.Icon 有方法直接由指针获取图标
    System.IO.FileStream 可以由指针获取文件流等等
    指针也可以转换成 INT32/INT64 (我指的是IntPtr)
    当然,你想在C#里继续使用指针也是很可以的
      

  4.   

    ericzhangbo1982111 按照你的那种方法转化了 还是不行一直都是提示NotSupportedException 
    lujiaxing2007 我要实现的是调用C++的dll读取SIM卡的联系人记录,但是调用这个api的时候出问题
      

  5.   

    ..不好意思 每仔细看。
    HRESULT SimReadPhonebookEntries( 
      HSIM hSim
      DWORD dwLocation, 
      DWORD dwStartIndex, 
      LPDWORD lpdwCount, 
      LPSIMPHONEBOOKENTRYEX lpEntries, 
      LPDWORD lpdwBufferSize 
    ); DllImport("cellcore.dll",CallingConvention= CallingConvention.Winapi,CharSet= CharSet.Unicode)] 
    public static extern IntPtr SimReadPhonebookEntries(int hSim, int dwLocation, int dwStartIndex, int lpdwCount,ref SimPhoneBookEntries enteries, int lpdwBufferSize); HSIM是什么类型???
      

  6.   

    [DllImport("cellcore.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Ansi)]
            public static extern int SimReadPhonebookEntries(int hSim, int dwLocation, int dwStartIndex, ref int lpdwCount, IntPtr lpEntries, ref int lpdwBufferSize);             IntPtr entryPtr = Marshal.AllocHGlobal(Marshal.SizeOf(SimPhoneBookEntries));
                int count = 0;
                int bufferSize = 0;
                int result = SimReadPhonebookEntries(4, 5, 6, ref count, entryPtr, ref bufferSize);            SimPhoneBookEntries entries = (SimPhoneBookEntries)Marshal.PtrToStructure(entryPtr, typeof(SimPhoneBookEntries));
                Marshal.FreeHGlobal(entryPtr);
      

  7.   

    不知道是什么原因,IntPtr entryPtr = Marshal.AllocHGlobal(Marshal.SizeOf(SimPhoneBookEntries));这段代码不能执行,报异常,使用其他的数据结构来分配空间就可以,问题似乎是SimPhoneBookEntries这个数据结构没有转化正确,不能得到他的Size所以不能分配到空间,不知道是什么原因造成这个数据结构连大小都无法得到,之前使用过的TCHAR数组都是转化为string,是不是因为有两个指向数据结构的指针没有转化对。需要怎么转化 
       
      

  8.   

    ericzhangbo1982111  hSim只是一个handle指针 通过另外的一个api来获得    
    [DllImport("cellcore.dll")]
    public static extern int SimInitialize(uint dwFlags, int lpfnCallBack, uint dwParam, ref int lphSim);这是一个微软的标准API,用来存取SIM卡的,就是在C#中调用的时候只有SimReadPhonebookEntries这个方法的转化不行,这个方法在C++实现的是把SIM卡中的记录存在一个SimPhoneBookEntries结构的数组中,但是C++中返回的只是这个结构数组的指针
      

  9.   

    新问题--如何在C#中传结构体数组来调用C++的dll
    此方法在C++中如下调用
    HRESULT hr1=SimGetPhonebookStatus(hSim,dwLocation,&dwCount,&dwTotal); //获得SIM卡中的记录条数保存在dwCount中;
    DWORD dwBufferSize = dwCount*sizeof (SIMPHONEBOOKENTRYEX);//计算dwCount条记录的地址空间
    LPSIMPHONEBOOKENTRYEX lpSimPBEx =(LPSIMPHONEBOOKENTRYEX)LocalAlloc(LPTR,dwBufferSize);//分配dwCount条记录的地址空间,
    HRESULT hr = SimReadPhonebookEntries(hSim,dwLocation, dwStartIndex, &dwCount, lpSimPBEx,&dwBufferSize);//将dwCount条记录读入到lpSimPBEx指向的空间中
    for(int i=1;i<dwCount;i++)
    ++lpSimPBEx;//通过移动指针来读取每一条记录
    我在c#中的调用如下:
    SimWrap.SimGetPhonebookStatus(hSim, SimWrap.SIM_PBSTORAGE_SIM, ref phoneUsed, ref phoneTotal);
    SimWrap.SimPhoneBookEntries[] simentries = SimWrap.SimPhoneBookEntries[5];
    int size = Marshal.SizeOf(typeof(SimWrap.SimPhoneBookEntries)) * 5;
    IntPtr entry= Marshal.AllocHGlobal(size);
    int buffersize=size;
    int result= SimWrap.SimReadPhonebookEntries(hSim, SimWrap.SIM_PBSTORAGE_SIM, 1, ref dw, entry, ref buffersize);
    simentries =(SimWrap.SimPhoneBookEntries[])Marshal.PtrToStructure(entry, simentries.GetType());
    这样调用的话就是在最后一条语句的地方程序挂掉,但是如果只新建一个而不是五个SimPhoneBookEntries的时候simentries =(SimWrap.SimPhoneBookEntries)Marshal.PtrToStructure(entry, simentries.GetType());就能得到第一条记录。
    读5条的时候其实通过VStudio的内存查看窗口也可以看到其余的记录,可是不知道怎么转化才能得到SimPhoneBookEntries数组。
    希望高手继续指教
      

  10.   

    你可以在entry上加上偏移,一般是结构的size,就能得到下一个结构的指针位置了。然后使用相同的代码获取下一个结构。
      

  11.   

    for (int i = 0; i < 数量; i++)
                    {
                        数组[i] = (类型)Marshal.PtrToStructure(输出指针(intptr对象), typeof(类型));
                        iter = (IntPtr)((int)iter + Marshal.SizeOf(typeof(类型)));
                    }
      

  12.   

    你好,不知道你解决问题没有?我现在在转换结构体时也是在那里显示NotSupportedException.