我如何编组列表<int>?
Posted
技术标签:
【中文标题】我如何编组列表<int>?【英文标题】:How do i marshal list<int>? 【发布时间】:2012-04-23 22:46:05 【问题描述】:我在 c++ 中有一个 dll,它返回列表,我想在我的 c# 应用程序中将它用作列表
[DllImport("TaskLib.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public static extern List<int> GetProcessesID();
public static List<int> GetID()
List<int> processes = GetProcessesID();//It is impossible to pack a "return value": The basic types can not be packed
//...
【问题讨论】:
std::list<>
和 System.Collections.Generic.List<>
在各方面都不同。除非您编写 C++/CLI shim,否则您的 C++ 代码将只需要根据 POD 类型工作——返回标准库对象永远不会工作。
已向 here 提出了相反的问题(编组并将列表从 C# 传递到 C++),这可能会有所帮助。
我认为您可以进行这种封送处理的唯一方法是编写一个 C++/CLI 中间函数来“手动”执行转换。
@loshurik:C++/CLI 桥接函数,能够同时使用std::list<>
和.NET 的List<>
应该返回List<>
,在填充了从@987654328 获得的数据之后@.
@loshurik :不,因为那样您将不知道列表的长度,也不知道如何释放内存。您最好的选择是 C++/CLI shim,或者让函数获取一个预先分配的缓冲区并填充它(而不是返回一个新分配的缓冲区)。
【参考方案1】:
每贾里德帕:
在任何互操作方案中通常不支持泛型。如果您尝试编组泛型类型或值,PInvoke 和 COM 互操作都将失败。因此,我希望 Marshal.SizeOf 在这种情况下未经测试或不受支持,因为它是 Marshal 特定的函数。
见: Marshalling .NET generic types
【讨论】:
【参考方案2】:一种可能的情况
c++端
struct ArrayStruct
int myarray[2048];
int length;
;
extern "C" __declspec(dllexport) void GetArray(ArrayStruct* a)
a->length = 10;
for(int i=0; i<a->length; i++)
a->myarray[i] = i;
c#端
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ArrayStruct
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2048)]
public int[] myarray;
public int length;
[DllImport("TaskLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GetArray(ref ArrayStruct a);
public void foo()
ArrayStruct a = new ArrayStruct();
GetArray(ref a);
【讨论】:
以上是关于我如何编组列表<int>?的主要内容,如果未能解决你的问题,请参考以下文章