//声明
typedef int SMTK_INT;
typedef unsigned int SMTK_UINT;
typedef unsigned long SMTK_DWORD;
typedef unsigned long SMTK_HANDLE;
//结构typedef struct _tagSmtkChannel /* 通道 */
{
SMTK_INT nID; /* 通道号 */
SMTK_INT nType; /* 见(通道类型定义) */
char szName[StringLength]; /* 通道名称 */
} SmtkChannel, *PSmtkChannel;typedef struct _tagSmtkDeviceResource /* 设备资源 */
{
char szPUID[16]; /* PUID */
char szName[StringLength]; /* 设备名称 */
SMTK_INT nChannelCount; /* 通道数量 */
SmtkChannel stChannel[1]; /* 通道数组 */
} SmtkDeviceResource, *PSmtkDeviceResource;
//方法/**************** 设备配置接口 ***************/
SMTK_INT SMTK_GetDeviceResource(SMTK_HANDLE hHandle, PSmtkDeviceResource pDeviceResource, SMTK_DWORD dwBufferLength);
//调用
m_sWndPair[m_iWndPair].hSmtk 指设备信息
m_sWndPair[m_iWndPair].hSmtk = SMTK_Login(csUser, csPas, szBufIP, 3456);
  BYTE Buffer[1024] = {0};
SmtkDeviceResource* pSmtkDeviceResource = (SmtkDeviceResource*)Buffer;
SMTK_INT iGet = SMTK_GetDeviceResource(m_sWndPair[m_iWndPair].hSmtk, pSmtkDeviceResource, 1024);
if(iGet != 0)
{
MessageBox("获取设备资源失败!");
return;
}下面是我的
  /// <summary>
  /// 设备资源
  /// </summary>
  public struct SmtkDeviceResource
  {
  ///</summary>  
  /// char szPUID[16]; szPUID
  /// </summary>  
  public string szPUID;  ///</summary>  
  /// char szPUID[32]; szName 设备名称 
  /// </summary>  
  public string szName;
  /// <summary>
  /// 通道数量 
  /// </summary>
  public int nChannelCount;
  /// <summary>
  /// 通道数组
  /// </summary>
  ///[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
  public SmtkChannel[] stChannel;
  }  ///通道信息
  public struct SmtkChannel
  {
  /// <summary>
  /// 通道号
  /// </summary>
  public int nID;  /// <summary>
  /// 见(通道类型定义)
  /// </summary>
  public int nType;  ///</summary>  
  /// char szPUID[32]; szName 通道名称 
  /// </summary>  
  public string szName;
  }  /// <summary>
  /// 获取设备信息
  /// </summary>
  /// <param name="hHandle"></param>
  /// <param name="pDeviceResource"></param>
  /// <param name="dwBufferLength"></param>
  /// <returns></returns> [DllImport("SMTK.dll")]
  public static extern int SMTK_GetDeviceResource(IntPtr hHandle, IntPtr pDeviceResource, int dwBufferLength);
//调用
    byte[] vBuffer = new byte[1024];
  IntPtr vAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 取得内存首地址  int cmd = SmartSDK.SMTK_GetDeviceResource(m_hSmtk, vAddress, vBuffer.Length);  SmtkDeviceResource entries = (SmtkDeviceResource)BytesToStruct(vBuffer, typeof(SmtkDeviceResource));报 C# 尝试读取或写入受保护的内存。这通常指示其他内存已损坏
求高人指教
private static object BytesToStruct(byte[] bytes, Type strcutType)
  {
  int size = Marshal.SizeOf(strcutType);
  IntPtr buffer = Marshal.AllocHGlobal(size);
  try
  {
  Marshal.Copy(bytes, 0, buffer, size);
  return Marshal.PtrToStructure(buffer, strcutType);
  }
  finally
  {
  Marshal.FreeHGlobal(buffer);
  }
  }

解决方案 »

  1.   

    把c++程序写完整直接打成dll
    然后通过引用可以实现调用
    这样改代码其不痛苦
      

  2.   

    他们的代码已经打包成dll了 贴上去的是C++的源码demo
      

  3.   

    结构体和函数映射错误:  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
      public struct SmtkDeviceResource
      {
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
         public string szPUID;     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
         public string szName;     public uint nChannelCount;     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
         public SmtkChannel[] stChannel;
      }  ///通道信息
      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
      public struct SmtkChannel
      {
          public uint nID;      public uint nType;      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]  
          public string szName;
      }
      [DllImport("SMTK.dll")]
      public static extern int SMTK_GetDeviceResource(uint hHandle, ref SmtkDeviceResource pDeviceResource, uint dwBufferLength);
    有个疑问:
    typedef struct _tagSmtkDeviceResource /* 设备资源 */
    {
    char szPUID[16]; /* PUID */
    char szName[StringLength]; /* 设备名称 */
    SMTK_INT nChannelCount; /* 通道数量 */
    SmtkChannel stChannel[1]; /* 通道数组 */
    } SmtkDeviceResource, *PSmtkDeviceResource;既然结构体里有指示通道数量 的成员,后面定义一个SmtkChannel stChannel[1]; /* 通道数组 */
    这是一种很奇怪的做法,直接定义指针更合理些。