首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

C#调用C++DLL传接结构体数组的终极解决方案

2013-09-18 
C#调用C++DLL传递结构体数组的终极解决方案在项目开发时,要调用C封装的DLL,普通的类型C#上一般都对应,只要

C#调用C++DLL传递结构体数组的终极解决方案

在项目开发时,要调用C++封装的DLL,普通的类型C#上一般都对应,只要用DllImport传入从DLL中引入函数就可以了。但是当传递的是结构体、结构体数组或者结构体指针的时候,就会发现C#上没有类型可以对应。这时怎么办,第一反应是C#也定义结构体,然后当成参数传弟。然而,当我们定义完一个结构体后想传递参数进去时,会抛异常,或者是传入了结构体,但是返回值却不是我们想要的,经过调试跟踪后发现,那些值压根没有改变过,代码如下。

[DllImport("workStation.dll")]        private static extern bool fetchInfos(IntPtr infosIntPtr);        [DllImport("workStation.dll")]        private static extern bool fetchInfos(byte[] infos);        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]        public struct Info        {            public int OrderNO;            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]            public byte[] UniqueCode;            public float CpuPercent;        };           private void buttonTest_Click(object sender, EventArgs e)        {            try            {                int count = 128;                int size = Marshal.SizeOf(typeof(Info));                byte[] inkInfosBytes = new byte[count * size];                                if (fetchInfos(inkInfosBytes))                {                    MessageBox.Show("Fail");                    return;                }                Info[] infos = new Info[count];                for (int inkIndex = 0; inkIndex < count; inkIndex++)                {                    byte[] inkInfoBytes = new byte[size];                    Array.Copy(inkInfosBytes, inkIndex * size, inkInfoBytes, 0, size);                    infos[inkIndex] = (Info)bytesToStruct(inkInfoBytes, typeof(Info));                }                string message = "";                foreach (Info info in infos)                {                    message += string.Format("OrderNO={0}\r\nUniqueCode={1}\r\nCpu={2}",                                           info.OrderNO,                                           Encoding.UTF8.GetString(info.UniqueCode),                                           info.CpuPercent                                           );                }                MessageBox.Show(message);            }            catch (System.Exception ex)            {                MessageBox.Show(ex.Message);            }        }        #region bytesToStruct        /// <summary>        /// Byte array to struct or classs.        /// </summary>        /// <param name=”bytes”>Byte array</param>        /// <param name=”type”>Struct type or class type.        /// Egg:class Human{...};        /// Human human=new Human();        /// Type type=human.GetType();</param>        /// <returns>Destination struct or class.</returns>        public static object bytesToStruct(byte[] bytes, Type type)        {            int size = Marshal.SizeOf(type);//Get size of the struct or class.                      if (bytes.Length < size)            {                return null;            }            IntPtr structPtr = Marshal.AllocHGlobal(size);//Allocate memory space of the struct or class.             Marshal.Copy(bytes, 0, structPtr, size);//Copy byte array to the memory space.            object obj = Marshal.PtrToStructure(structPtr, type);//Convert memory space to destination struct or class.                     Marshal.FreeHGlobal(structPtr);//Release memory space.                return obj;        }        #endregion
对于实在想不到要怎么传数据的时候,可以考虑byte数组来传(即便是整型也可以,只要是开辟4字节(在32位下)),只要开的长度对应的上,在拿到数据后,要按类型规则转换成所要的数据,一般都能达到目的。

转载请注明出处http://blog.csdn.net/xxdddail/article/details/11781003

热点排行