题
我处理的一组通过动态分配的阵列返回数据本地函数。该函数采用一个参考指针作为输入,然后将其指向所得阵列。
例如:
typedef struct result
{
//..Some Members..//
}
int extern WINAPI getInfo(result**);
呼叫后,“结果”指向结果的空终止阵列*。
我想创建从该非托管阵列的管理列表。我可以执行以下操作:
struct Result
{
//..The Same Members..//
}
public static unsafe List<Result> getManagedResultList(Result** unmanagedArray)
{
List<Result> resultList = new List<Result>();
while (*unmanagedArray != null)
{
resultList.Add(**unmanagedArray);
++unmanaged;
}
return result;
}
这工作,这将是乏味和丑陋重新实现每种类型结构的,我将不得不处理(〜35)。我想一个解决方案,已经过去结构的阵列中的类型通用的。为此,我想:
public static unsafe List<T> unmanagedArrToList<T>(T** unmanagedArray)
{
List<T> result = new List<T>();
while (*unmanagedArray != null)
{
result.Add((**unmanagedArray));
++unmanagedArray;
}
return result;
}
但是,这不会编译,因为你不能“取的地址,获得的大小,或声明指针到托管类型(‘T’)”。
我也试图做到这一点,而无需使用不安全的代码,但我跑成Marshal.Copy()需要知道的非托管数组的大小的问题。我只能确定此使用不安全的代码,因此似乎是没有好处在这种情况下使用Marshal.Copy()。
我在想什么?可能有人提出一个通用的办法解决这个问题?
解决方案
您可以做一个合理的假设,所有指针的是大小和代表性是相同的(不知道C#规格保证了这一点,但在实践中,你会发现它是如此)。所以,你可以把你的T**
为IntPtr*
。另外,我看不出Marshal.Copy
将如何帮助你在这里,因为它仅具有内置类型的重载。所以:
public static unsafe List<T> unmanagedArrToList<T>(IntPtr* p)
{
List<T> result = new List<T>();
for (; *p != null; ++p)
{
T item = (T)Marshal.PtrToStructure(*p, typeof(T));
result.Add(item);
}
return result;
}
当然,你需要有明确的转换,只要你把这个给IntPtr*
,但至少没有重复代码,否则。
其他提示
您表示:
Marshal.Copy()需要知道大小 非托管阵列。我只能 确定这一点使用不安全的代码
看来你错过 Marshal.SizeOf()。
这是你在帖子中提到的东西,这可能足以解决你的问题。 (另外,你的函数的参数可能需要对象**代替T **)
不隶属于 StackOverflow