Returnering af en konpleks struktur fra en dll
Jeg fik hjælp til at kalde en c++ dll funktion med en struktur i dette spm: http://www.eksperten.dk/spm/842083.Men jeg har også funktioner der returnere strukturer og for tiden har jeg klaret det ved:
namespace wpGrabDotNet.DllCode
{
public class PointerToStruct<T> : IDisposable
where T : struct
{
private T? outputStruct = null;
public T? ToStruct
{
get
{
return outputStruct;
}
}
public PointerToStruct(IntPtr ptr)
{
try
{
if (ptr != IntPtr.Zero)
{
//outputStruct = new T();
outputStruct = (T) Marshal.PtrToStructure(ptr, typeof(T));
}
}
catch(Exception ex)
{
outputStruct = null;
throw new Exception(ex.Message);
}
}
public void Dispose()
{
outputStruct = null;
}
}
}
Og strukturen der modtages er defineret ved (WPGRAB_STATUS_ENUM er en enumeration):
[StructLayout(LayoutKind.Sequential, CharSet=DLL_CHAR_SET)]
public struct WPGrabUrlResourceStruct
{
public int id;
public int masterId;
public int errCode;
//char* localFileName;
public string url;
public string errMsg;
public WPGRAB_STATUS_ENUM status;
};
[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;
};
public struct WPGrabResourceFoundStruct
{
public int masterId;
public WPGrabUrlResourceStruct? webpagesList;
public WPGrabUrlResourceStruct? imagesList;
public WPGrabUrlResourceStruct? otherList;
};
Jeg kalder så dll funktionen med:
[DllImport(DLL_NAME, CallingConvention = DLL_CC, CharSet = DLL_CHAR_SET, EntryPoint = "WPGrabGetFoundResources")]
private static extern IntPtr WPGrabGetFoundResourcesInt(int index);
public static WPGrabResourceFoundStruct? WPGrabGetFoundResources(int index)
{
using (var output = new PointerToStruct<WPGrabResourceFoundStructInt>(WPGrabGetFoundResourcesInt(index)))
{
WPGrabResourceFoundStruct tmp = new WPGrabResourceFoundStruct();
tmp.webpagesList = (WPGrabUrlResourceStruct?) (new PointerToStruct<WPGrabUrlResourceStruct>(output.ToStruct.Value.webpagePtr)).ToStruct;
tmp.imagesList = (WPGrabUrlResourceStruct?)(new PointerToStruct<WPGrabUrlResourceStruct>(output.ToStruct.Value.imagePtr)).ToStruct;
tmp.otherList = (WPGrabUrlResourceStruct?)(new PointerToStruct<WPGrabUrlResourceStruct>(output.ToStruct.Value.otherPtr)).ToStruct;
return tmp;
}
}
Det virker meget besværligt... Er man virkelig nødt til selv at kopiere inner strukturer (f.eks. webpagesList) som kan være nullable??? Eller er der en bedre løsning???