我有一个结构:
public struct ResultOfStrategy
{
......
public double[] param;
public IntPtr ptr;
}
我将此结构放入DLL中,有必要在该结构中返回数组的值
result = new ResultOfStrategy[(int)length];
for(int i = 0; i < (int)length; i++)
{
result[i].param = new double[10];
}
// try... finally trick to be sure that the code isn't interrupted by asynchronous exceptions
try
{
}
finally
{
handle = GCHandle.Alloc(result, GCHandleType.Pinned);
}
return handle.AddrOfPinnedObject();
我得到一个错误-该对象包含的数据不是原始数据或需要转换的数据。如何解决此问题?
P.s。我想从C#中以C ++形式传递一个结构数组,其中将包含普通变量和1个类型为double的数组。
答案 0 :(得分:0)
我不完全知道您想做什么,但是,只有一件事:您无法轻松固定ResultOfStrategy
结构。因此,您必须创建该struct
...
public struct ResultOfStrategy
{
public IntPtr ptr;
public double[] param;
}
public struct ResultOfStrategyImpl
{
public IntPtr ptr;
public IntPtr param;
}
public static IntPtr Test(int length, out GCHandle[] handlesToBeFreed)
{
var result = new ResultOfStrategy[(int)length];
for (int i = 0; i < (int)length; i++)
{
result[i].param = new double[10];
}
// Copy to new blittable object
var result2 = new ResultOfStrategyImpl[result.Length];
for (int i = 0; i < result.Length; i++)
{
result2[i].ptr = result[i].ptr;
}
handlesToBeFreed = new GCHandle[length + 1];
GCHandle handle;
// try... finally trick to be sure that the code isn't interrupted by asynchronous exceptions
try
{
}
finally
{
for (int i = 0; i < result.Length; i++)
{
handle = GCHandle.Alloc(result2[i], GCHandleType.Pinned);
handlesToBeFreed[i] = handle;
result2[i].param = handle.AddrOfPinnedObject();
}
handle = GCHandle.Alloc(result2, GCHandleType.Pinned);
handlesToBeFreed[result.Length] = handle;
}
return handle.AddrOfPinnedObject();
}
public static void FreeHandles(GCHandle[] handles)
{
if (handles != null)
{
for (int i = 0; i < handles.Length; i++)
{
handles[i].Free();
}
}
}
使用方式:
GCHandle[] handlesToBeFreed = null;
try
{
IntPtr ptr = Test(10, out handlesToBeFreed);
// Work with ptr
}
finally
{
FreeHandles(handlesToBeFreed);
}