Ich halte einen Access bekommen, wenn die folgenden von einem externen DLL Aufruf:Access während P/Invoke Hilfe
FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, pMapping, out PagePerSector);
, die einen Prototyp hat, dass ich Setup als solche haben:
[DllImport("Files.DLL", SetLastError = true)]
public static extern uint FILES_GetMemoryMapping(
[MarshalAs(UnmanagedType.LPStr)]
string pPathFile,
out ushort Size,
[MarshalAs(UnmanagedType.LPStr)]
string MapName,
out ushort PacketSize,
IntPtr pMapping,
out byte PagesPerSector);
Jetzt , das Argument, das dies verursacht, ist höchstwahrscheinlich der 5. (IntPtr pMapping). Ich habe diesen Code von einer C++ App in C# portiert. Das fünfte Argument oben ist ein Zeiger auf eine Struktur, die auch einen Zeiger auf eine andere Struktur enthält. Unten ist, wie ich diese sctructs Setup:
[StructLayout(LayoutKind.Sequential)]
public struct MappingSector
{
[MarshalAs(UnmanagedType.LPStr)]
public string Name;
public uint dwStartAddress;
public uint dwAliasedAddress;
public uint dwSectorIndex;
public uint dwSectorSize;
public byte bSectorType;
public bool UseForOperation;
public bool UseForErase;
public bool UseForUpload;
public bool UseForWriteProtect;
}
[StructLayout(LayoutKind.Sequential)]
public struct Mapping
{
public byte nAlternate;
[MarshalAs(UnmanagedType.LPStr, SizeConst=260)]
public string Name;
public uint NbSectors;
public IntPtr pSectors;
}
Die C++ Äquivalent davon sind wie folgt:
typedef struct {
char* Name;
DWORD dwStartAddress;
DWORD dwAliasedAddress;
DWORD dwSectorIndex;
DWORD dwSectorSize;
BYTE bSectorType;
BOOL UseForOperation;
BOOL UseForErase;
BOOL UseForUpload;
BOOL UseForWriteProtect;
} MAPPINGSECTOR, *PMAPPINGSECTOR;
typedef struct {
BYTE nAlternate;
char Name[MAX_PATH]; // MAX_PATH = 260
DWORD NbSectors;
PMAPPINGSECTOR pSectors;
} MAPPING, *PMAPPING;
Ich habe ein Gefühl, das ich etwas falsch gemacht haben entweder mit der Portierung über diese Strukturen oder Portierung über der Funktionsprototyp. Eine Marshalling-Ausgabe von Somesort.
Die Funktion ganz oben in diesem Post wird zweimal in meinem Code aufgerufen. Einmal mit pMapping auf Null gesetzt (dies bringt einen Wert in "size"). Der Speicher wird dann unter Verwendung dieses Größenparameters für eine neue Struktur zugewiesen, und die Funktion wird nun erneut aufgerufen, wobei ein Zeiger auf diesen zugewiesenen Speicherplatz für pMapping verwendet wird. (pMapping hat auch einen Zeiger für die andere Struktur, der während dieser Zeit auch etwas Platz zugewiesen wird).
ist der alten C++ Code, der dies erreicht:
ich die richtige Menge an Speicherplatz nicht war die ZuteilungFILES_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));
printf("mapsectorsize: <%d>\n", football);
printf("pMappingsize: <%d>\n", f2);
// Get the mapping info
FILES_GetMemoryMapping((LPSTR)(LPCTSTR)MapFile, &Size, (LPSTR)(LPCTSTR)MapName, &PacketSize, pMapping, &PagePerSector);
ich zunächst dachte, so dass ich den alten C++ Code oben ausprobiert und fand heraus, dass:
sizeof(MAPPING) = 272
and
sizeof(PMAPPINGSECTOR) = 40
habe ich die gleiche Prüfung in meinem C# -Code und fanden die folgende:
Marshal.SizeOf(new Mapping()) = 16
and
Marshal.SizeOF(new MappingSector()) = 40
Wir haben hier ein Problem. Die Mapping-Struktur sollte eine Größe von 272 haben, aber ihre einzige 16. Ich denke, ich könnte nur eine schnelle Lösung, ich manuell 272 statt 16 hier zugeordnet, aber es immer noch mit einer AccessViolationException.
Haben Sie eine Idee, wie Sie das beheben können? Oder was könnte noch schief gehen?
Ich denke, das läuft auf die "Structs kann keine explizite parameterlose Konstruktoren" Einschränkung ... – dlchambers