本文介绍了获得从本地的dll结构数组到C#应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我有一个C#.NET CF 2.0项目中,我需要在本地C ++ DLL调用方法。这种本地方法返回一个类型 TableEntry 的数组。在本地方法被调用的时候,我不知道该阵列将多大。 如何从本地DLL到C#项目拿到桌子吗?下面是有效的什么,我现在有。 //在C#.NET CF 2.0项目 [StructLayout(LayoutKind。顺序)] 公共结构TableEntry { [的MarshalAs(UnmanagedType.LPWStr)]公共字符串描述; 公众诠释项目; 公众诠释another_item; 公众的IntPtr some_data; } 函数[DllImport(MYDLL.DLL, CallingConvention = CallingConvention.Winapi,字符集= CharSet.Auto)] 公共静态外部布尔的GetTable(参考TableEntry []表); SomeFunction() { TableEntry []表= NULL; BOOL成功=的GetTable(参见表格); //在这一点上,该表是空的} //在本地C ++ DLL 的std ::矢量< TABLE_ENTRY> global_dll_table; 的externC__declspec(dllexport)的布尔的GetTable(TABLE_ENTRY *表) {表=&放大器; global_dll_table.front(); 返回真; } 谢谢, PaulH 解决方案 在编组未知大小的数组从原产地到管理,我觉得最好的策略如下: 键入托管代码数组的IntPtr 有本地代码同时返回数组和大小参数。 手动从的IntPtr 数据元帅在托管方自定义结构。 因此我会进行以下更改你的代码。 本机: 的externC__declspec(dllexport)的布尔的GetTable(TABLE_ENTRY **表,__int32 * pSize) { *表=&放大器; global_dll_table.front(); *的pSize =的static_cast&所述; INT32>(global_dll_table.size()); 返回真; } 管理 函数[DllImport(MYDLL.DLL, CallingConvention = CallingConvention.Winapi,字符集= CharSet.Auto)] [返回:的MarshalAs(UnmanagedType .I1)] 公共静态外部布尔的GetTable(出的IntPtr arrayPtr,OUT INT大小); 公共静态列表< TableEntry>的GetTable(){ VAR arrayValue = IntPtr.Zero; 变种大小= 0; 无功名单=新名单,LT; TableEntry>(); 如果(的GetTable(出arrayValue,出大小)!){返回列表; } VAR tableEntrySize = Marshal.SizeOf(typeof运算(TableEntry)); 为(VAR I = 0; I<大小;我++){ VAR CUR =(TableEntry)Marshal.PtrToStructure(arrayValue的typeof(TableEntry)); list.Add(现); arrayValue =新的IntPtr(arrayValue.ToInt32()+ tableEntrySize); } 返回列表; } I have a C# .NET 2.0 CF project where I need to invoke a method in a native C++ DLL. This native method returns an array of type TableEntry. At the time the native method is called, I do not know how large the array will be.How can I get the table from the native DLL to the C# project? Below is effectively what I have now.// in C# .NET 2.0 CF project[StructLayout(LayoutKind.Sequential)]public struct TableEntry{ [MarshalAs(UnmanagedType.LPWStr)] public string description; public int item; public int another_item; public IntPtr some_data;}[DllImport("MyDll.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]public static extern bool GetTable(ref TableEntry[] table);SomeFunction(){ TableEntry[] table = null; bool success = GetTable( ref table ); // at this point, the table is empty}// In Native C++ DLLstd::vector< TABLE_ENTRY > global_dll_table;extern "C" __declspec(dllexport) bool GetTable( TABLE_ENTRY* table ){ table = &global_dll_table.front(); return true;}Thanks,PaulH 解决方案 When marshalling an array of unknown size from native to managed I find the best strategy is as followsType the array to IntPtr in managed codeHave the native code return both the array and a size parameter. Manually marshal the data from IntPtr to the custom struct on the managed side. As such I would make the following changes to your code. Native:extern "C" __declspec(dllexport) bool GetTable( TABLE_ENTRY** table, __int32* pSize ){ *table = &global_dll_table.front(); *pSize = static_cast<int32>(global_dll_table.size()); return true;}Managed:[DllImport("MyDll.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)][return: MarshalAs(UnmanagedType.I1)]public static extern bool GetTable(out IntPtr arrayPtr, out int size);public static List<TableEntry> GetTable() { var arrayValue = IntPtr.Zero; var size = 0; var list = new List<TableEntry>(); if ( !GetTable(out arrayValue, out size)) { return list; } var tableEntrySize = Marshal.SizeOf(typeof(TableEntry)); for ( var i = 0; i < size; i++) { var cur = (TableEntry)Marshal.PtrToStructure(arrayValue, typeof(TableEntry)); list.Add(cur); arrayValue = new IntPtr(arrayValue.ToInt32() + tableEntrySize); } return list;} 这篇关于获得从本地的dll结构数组到C#应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 09-21 23:57