PInvoke

15/09/2009 - 16:41 von Stefan Simon | Report spam
Hallo,

ich habe eine Struktur, die sieht so aus:

type TMsgData = packed record
Text: array [0..65535] of char;
end;

bzw.

typedef struct
{
char Text[65536];
}

und eine Methode, die so aussieht:

function WibGetMessage(TypeOfMessage:integer; Index: integer;
Destination: PmsgData):integer;

bzw.
__declspec(dllimport)int __stdcall WibGetMessage(int TypeOfMessage,
int Index, void *Destination);


daraus habe ich folgendes gemacht:

[StructLayout(LayoutKind.Sequential)]
public struct TMsgData
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)]
Char[] Text;
public override String ToString()
{
return new String(this.Text);
}
}

[DllImport("wibdll.dll")]
public static extern Int32 WibGetMessage(eTypeOfMessage
TypeOfMessage,
Int32 Index, ref TMsgData MsgData);

Beim Aufruf der Funktion bekomme ich den Fehler, der 3. Parameter könne
nicht gemarshalt werden, da er zu groß sei.

Auch
[DllImport("wibdll.dll")]
public static extern Int32 WibGetMessage(eTypeOfMessage
TypeOfMessage,
Int32 Index, ref String MsgData);

und
[DllImport("wibdll.dll")]
public static extern Int32 WibGetMessage(eTypeOfMessage
TypeOfMessage,
Int32 Index, IntPtr MsgData);

in Verbindung mit Marshal.PtrToStructure bringen Fehler (versuch in
geschütztem Speicher zu schreiben)

Wie muss die Übersetzung in CSharp korrekt lauten?

tia,
Stefan
 

Lesen sie die antworten

#1 Stefan Simon
16/09/2009 - 11:41 | Warnen spam
typedef struct
{
char Text[65536];
} TMsgData

__declspec(dllimport)int __stdcall WibGetMessage(int TypeOfMessage,
int Index, void *Destination);



Ich habe das jetzt so gelöst:

[DllImport("wibdll.dll")]
unsafe public static extern Int32 WibGetMessage(eTypeOfMessage
TypeOfMessage,
Int32 Index, byte* MsgData);

byte[] Data = new byte[65536];
unsafe
{
fixed (byte* pData = Data)
{
Int32 result = WibGetMessage(item, index, pData);
}
}
String MsgData = System.Text.Encoding.ASCII.GetString(Data);

Möch stört dabei allerdings der unsichere Codebereich.
Fàllt jemandem etwas besseres ein?

... nochmal Testen ...

ok, hat sich erledigt. Ich mach das jetzt so:

[DllImport("wibdll.dll")]
public static extern Int32 WibGetMessage(eTypeOfMessage TypeOfMessage,
Int32 Index, IntPtr MsgData);

byte[] Data = new byte[65536];
IntPtr pData;
GCHandle gch = GCHandle.Alloc(Data,GCHandleType.Pinned);
pData = gch.AddrOfPinnedObject();
Int32 result = WibGetMessage(item, index, pData);
String MsgData = System.Text.Encoding.ASCII.GetString(Data);
gch.Free();

Stefan

Ähnliche fragen