Marshal Strukture med arrays og string
Jeg har en funktion, der får følgende struktur som input:[StructLayout(LayoutKind.Sequential, CharSet=DLL_CHAR_SET)]
public struct WPGrabUrlResourceStruct
{
public int id;
public int masterId;
public int errCode;
public string url;
public string errMsg;
public WPGRAB_STATUS_ENUM status;
};
public struct WPGrabResourceFoundStruct
{
public int masterId;
public WPGrabUrlResourceStruct[] webpagesList;
public WPGrabUrlResourceStruct[] imagesList;
public WPGrabUrlResourceStruct[] otherList;
};
Den skal jeg have konvertere til strukturen:
[StructLayout(LayoutKind.Sequential)]
public struct WPGrabResourceFoundStructInt
{
public int masterId;
public int webpageCount;
public int imagesCount;
public int otherCount;
public IntPtr webpagePtr;
public IntPtr imagePtr;
public IntPtr otherPtr;
};
For at kunne kalde en dll funktion, der har til opgave af frigøre hukommelse.
Jeg har forsøgt med (efter inspiration fra http://forums.msdn.microsoft.com/en-US/csharpgeneral/thread/a0cdf1eb-64a2-4893-9b52-14649006d5d8/):
[DllImport(DLL_NAME, CallingConvention = DLL_CC, CharSet = DLL_CHAR_SET, EntryPoint = "WPGrabFreeFoundResourcesStruct")]
private static extern void WPGrabFreeFoundResourcesStructInt(IntPtr resources);
public static void WPGrabFreeFoundResourcesStruct(WPGrabResourceFoundStruct? resources)
{
if (resources != null)
{
WPGrabResourceFoundStructInt tmp = new WPGrabResourceFoundStructInt();
int sizeOfStruct = 0;
Int64 addr = 0;
tmp.masterId = resources.Value.masterId;
tmp.webpageCount = resources.Value.webpagesList.GetLength(0);
if (tmp.webpageCount > 0)
{
sizeOfStruct = Marshal.SizeOf(resources.Value.webpagesList.GetValue(0)); //Marshal.SizeOf(resources.Value.webpagesList.GetValue(0));
tmp.webpagePtr = Marshal.AllocHGlobal(sizeOfStruct * tmp.webpageCount);
addr = tmp.webpagePtr.ToInt64();
for (int i = 0; i < tmp.webpageCount; i++)
{
Marshal.StructureToPtr(resources.Value.webpagesList[i], (IntPtr) (addr + i * sizeOfStruct), false);
// tmp.webpagePtr[addr + i * sizeOfStruct] = (new StructToPointer<WPGrabUrlResourceStruct>(resources.Value.webpagesList(i)).ToPtr)
}
}
else
{
tmp.webpagePtr = IntPtr.Zero;
}
tmp.imagesCount = 0;
tmp.imagePtr = IntPtr.Zero;
tmp.otherCount = 0;
tmp.otherPtr = IntPtr.Zero;
using (var t = new StructToPointer<WPGrabResourceFoundStructInt>(tmp))
{
WPGrabFreeFoundResourcesStructInt(t.ToPtr);
}
}
}
StructToPointer kan findes her: http://www.eksperten.dk/spm/842083.
Mit problem er at når jeg køre programmet, så får jeg fint allokeret hukommelsen og i WPGrabFreeFoundResourcesStructInt kan jeg se de data jeg sender med, men når jeg via delete[] errMsg (fra WPGrabUrlResourceStruct), så får jeg assertion. Nogen ideer til hvad problemet er???