1. 程式人生 > >c#呼叫C/C++ DLL,傳入指標陣列(指標指向自定的結構體)

c#呼叫C/C++ DLL,傳入指標陣列(指標指向自定的結構體)

來源:http://bbs.csdn.net/topics/380165851

依靠以下文章:解決問題。

、、、、、、、、、、、、、、、、、、、、

可以用Marshal.StruectToPtr哦。

、、、、、、、、、、、、、、

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct Query
        {
            public String Address;
            public Int32 Port;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public String User;
        }

        public class LibWrap
        {
            //這裡通過值傳遞指標陣列,C++中不能改變陣列大小
            //如需要此功能,可通過引用傳遞指標陣列後再作處理(以IntPtr傳遞陣列首地址)
            [DllImport("MyDll.dll")]
            public static extern void GetResult([In, Out] IntPtr[] array, Int32 size);
        }

        static void Main(string[] args)
        {
            const int PointersCount = 11;    //指標數量

            IntPtr[] arrPointer = new IntPtr[PointersCount];

            //在C++中為每一個Query結構分配記憶體,並將指標賦入從C#傳入的指標陣列中
            LibWrap.GetResult(arrPointer, PointersCount);

            Query[] arrQuery = new Query[PointersCount];    //儲存處理好的Query
            for (int i=0;i<PointersCount;i++)
            {
                //arrQuery[i] = (Query)(Marshal.PtrToStructure(arrPointer[i], typeof(Query)));
                Marshal.PtrToStructure(arrPointer[i], arrQuery[i]);
                Console.WriteLine("Query{0}: Address {1}, Port {2}, User {3}", i, arrQuery[i].Address, arrQuery[i].Port, arrQuery[i].User);
            }
            Console.ReadKey();
        }


、、、、、、、、、、、、、、、、、、、、、、、

直接用IntPtr作為引數傳入就可以了;

陣列在記憶體中是順序儲存的,呼叫方法後IntPtr引數返回的是陣列第一個值的地址;
所以,陣列第N個元素的地址為IntPtr + N * sizeof(struct);
得到陣列元素的地址後,用Marshal.PtrToStructure轉化即可;