2009-04-08 18 views
4

Alle konvertieren, ist dies ein hier aus einer früheren Frage folgen: C# formatting external Dll function parametersWie ein IntPtr zurück in ein Objekt

hier speziell der Code, den ich C# zu konvertieren Ich versuche:

FILES_GetMemoryMapping((LPSTR)(LPCTSTR)MapFile, &Size, (LPSTR)MapName, &PacketSize, pMapping, &PagePerSector); 
// Allocate the mapping structure memory 
pMapping = (PMAPPING)malloc(sizeof(MAPPING)); 
pMapping->NbSectors = 0; 
pMapping->pSectors = (PMAPPINGSECTOR) malloc((Size) * sizeof(MAPPINGSECTOR)); 

// Get the mapping info 
FILES_GetMemoryMapping((LPSTR)(LPCTSTR)MapFile, &Size, (LPSTR)(LPCTSTR)MapName, &PacketSize, pMapping, &PagePerSector); 

Die Funktion "FILES_GetMemoryMapping" wird zweimal aufgerufen, ich rate zum ersten Mal, um die Größe der Struktur zu erhalten, und die zweite, um sie tatsächlich zu füllen.

Das "pMapping" ist ein Zeiger auf eine Struktur in C++, In meinem C# -Code habe ich pMapping als Typ IntPtr. Die nächste Zeile, die ich umwandeln kann in:

pMapping = Marshal.AllocHGlobal(Marshal.SizeOf(new UM0516.Mapping())); 

Mit (UM0516.Mapping) wird die Struktur. Cool, also habe ich gerade etwas Platz reserviert, auf den IntPtr zeigt. Jetzt für die nächste Zeile ... "pMapping-> NbSectors = 0;"

Wie soll ich in den jetzt zugewiesenen nicht verwalteten Speicherbereich einsteigen, geben Sie ihn als (UM0516.Mapping) -Struktur ein und setzen Sie eines seiner Mitglieder? Dann stellen Sie sicher, dass ich nicht zu sehr damit zu tun, so dass das zweite Mal, wenn ich "FILES_GetMemoryMapping" aufrufen, kann es jetzt diese Struktur verwenden ??

- Ok, ich habe ein paar Ratschläge genommen und jetzt haben diese:

ich das versucht, und ich bekomme eine Ausnahme auf dem ersten „FILES_GetMemoryMapping“ nennen

Here „Access unhandled war“ ist das, was Ich habe:

string filepath = @"C:\blah.blah"; 
string MapFile = @"D:\blah.blah"; 
UM0516.Mapping myMapping = new UM0516.Mapping(); 
IntPtr pMapping = Marshal.AllocHGlobal(Marshal.SizeOf(myMapping)); 
Marshal.StructureToPtr(myMapping, pMapping, false); 
ushort PacketSize = 0; 
ushort size = 0; 
string MapName = String.Empty; 
byte PagePerSector = 0; 

uint b7 = UM0516.FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, pMapping, out PagePerSector); 

Glauben Sie, dass diese Ausnahme vom Parameter "pMapping" kommt? Könnte das von etwas anderem kommen, an dem ich vorbeigekommen bin?

Antwort

10

Um die IntPtr zu bekommen, was Sie wollen, ist Ihre Struktur erstellen, alle Optionen festlegen, müssen Sie möglicherweise, den Speicher zuweisen wie Sie bereits haben, dann rufen ..

System.Runtime.InteropServices.Marshal.StructureToPtr(yourStructVariable, pMapping, false); 

Dadurch werden die Daten aus Ihrer Struktur in den zugewiesenen Speicher kopiert.

Um Daten aus dem Speicher in eine neue Struktur namens ‚mapping‘ zu kopieren, rufen Sie ...

UM0516.Mapping mapping = (UM0516.Mapping)System.Runtime.InteropServices.Marshal.PtrToStructure(pMapping, typeof(UM0516.Mapping)) 
0

Um einen IntPtr zurück in ein Objekt zu konvertieren, habe ich ein Verfahren, das dies tut:

if (ptrToUnwrap == IntPtr.Zero) 
    return null; 
GCHandle handle = (GCHandle)ptrToUnwrap; 
object handledObj = handle.Target; 
if (handles.unfreed.Contains(handle)) 
    handles.unfreed.Remove(handle); 
handle.Free(); 
return handledObj; 

(handles.unfreed ist eine Liste von unfreeded GCHandles, die automatisch freigegeben werden, wenn Griffe entfernt oder finialisiert werden)

Verwandte Themen