c#调用c++dll 结构体指针的问题

时间:2022-08-30 20:00:42
 c++dl函数
 int _stdcall TA_ReadCardSimple(AccountMsg * pAccMsg);
结构体
typedef struct
{
     char                      Name[21];                         /*姓名*/
       char                      SexNo[2];                          /*性别*/
       char                      DeptCode[19];                   /*部门代码*/
       unsigned int           CardNo;                            /*卡号*/
       unsigned int           AccountNo;                       /*帐号*/
       char                      StudentCode[21];               /*学号*/
       char                      IDCard[21];                       /*身份证号*/
       char                      PID[3];                              /*身份代码*/
       char                      IDNo[13];                          /*身份序号*/
       int                         Balance;                             /*现余额*/
       char                      Password[7];                      /*消费密码*/
       char                      ExpireDate[7];                    /*账户截止日期*/
       unsigned short       SubSeq;                             /*补助戳*/
       char                      IsOpenInSys;                     /*是否在本系统内开通*/
       short                     TerminalNo;                       /*终端号码,提取补助时需要填写*/
       short                     RetCode;                           /*后台处理返回值*/
       char                      Flag[16];                            /*状态(2004-08-26增加)*/
       char                      Pad[84];                      /*预留字段*/
 } AccountMsg;

我在c#里面引用
[DllImport("AIO_API.dll")]
        public static extern int TA_ReadCardSimple(ref  IntPtr pAccMsg);
定义结构体
[StructLayout(LayoutKind.Sequential)]
        public struct AccountMsg
        { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
            public byte[] Name;                         /*姓名*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
            public byte[] SexNo;                          /*性别*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 19)]
            public byte[] DeptCode;                   /*部门代码*/
             [MarshalAs(UnmanagedType.U4)]
            public uint CardNo;                            /*卡号*/
             [MarshalAs(UnmanagedType.U4)]
            public uint AccountNo;                       /*帐号*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
            public byte[] StudentCode;               /*学号*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
            public byte[] IDCard;                       /*身份证号*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            public byte[] PID;                              /*身份代码*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)]
            public byte[] IDNo;                          /*身份序号*/
           [MarshalAs(UnmanagedType.U4)]
            public uint Balance;                             /*现余额*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
            public byte[] Password;                      /*消费密码*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
            public byte[] ExpireDate;                    /*账户截止日期*/
             [MarshalAs(UnmanagedType.U4)]
            public uint SubSeq;                             /*补助戳*/
           [MarshalAs(UnmanagedType.U1)]
            public byte IsOpenInSys;                     /*是否在本系统内开通*/
            [MarshalAs(UnmanagedType.U4)]
            public uint TerminalNo;                       /*终端号码,提取补助时需要填写*/
           [MarshalAs(UnmanagedType.U4)]
            public uint RetCode;                           /*后台处理返回值*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] Flag;                            /*状态(2004-08-26增加)*/
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 84)]
            public byte[] Pad;                      /*预留字段*/
}

调用 IntPtr[] ptArray = new IntPtr[1];
            ptArray[0] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(AccountMsg)) * 1);
            IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(AccountMsg)));
            Marshal.Copy(ptArray, 0, pt, 1);         
           int  a = TA_ReadCardSimple(ref  pt);       
               msg1[0] =
               (AccountMsg)Marshal.PtrToStructure((IntPtr)((UInt32)pt + 0 * Marshal.SizeOf(typeof(AccountMsg)))
               , typeof(AccountMsg));
               MessageBox.Show(Convert.ToByte(msg1[0].Name[0]).ToString());
在倒数第二句报引发类型为“System.ExecutionEngineException”的异常。谁能帮看看谢谢

4 个解决方案

#1


直接将C#里面的结构体申明成string 类型,长度和C++结构体的长度一样就可以了,就象这样

// using System.Runtime.InteropServices;
 struct tagTest
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
        public string sName;
    }

#2


你说的这种试过了,但是还是这个异常

#3


确认下c++函数的定义,如果传回来的是单个结构体 

  [DllImport("AIO_API.dll", EntryPoint = "TA_ReadCardSimple", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int TA_ReadCardSimple(ref AccountMsg pAccountMsg);

同时在AccountMsg 结构体定义上加上这个声明
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
保证字节对齐
应该就可以了

#4


楼主的问题解决了吗?

#1


直接将C#里面的结构体申明成string 类型,长度和C++结构体的长度一样就可以了,就象这样

// using System.Runtime.InteropServices;
 struct tagTest
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
        public string sName;
    }

#2


你说的这种试过了,但是还是这个异常

#3


确认下c++函数的定义,如果传回来的是单个结构体 

  [DllImport("AIO_API.dll", EntryPoint = "TA_ReadCardSimple", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int TA_ReadCardSimple(ref AccountMsg pAccountMsg);

同时在AccountMsg 结构体定义上加上这个声明
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
保证字节对齐
应该就可以了

#4


楼主的问题解决了吗?