я получаю сообщение AccessViolationException при вызове вытекающих из внешнего DLL:AccessViolationException при P/Invoke Помощь
FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, pMapping, out PagePerSector);
который имеет прототип, который я установки как таковые:
[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);
сейчас , аргумент, который вызывает это, скорее всего, пятый (IntPtr pMapping). Я перенес этот код из C++-приложения в C#. 5-й аргумент выше - указатель на структуру, которая также содержит указатель на другую структуру. Ниже, как у меня есть эти sctructs установка:
[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;
}
C++ эквивалент этих следующим образом:
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;
У меня есть чувство, что я сделал что-то не так с любым переносом над этими структурами, или перенос через прототип функции. Маршалинская проблема somesort.
Функция, которая находится в верхней части этого сообщения, дважды вызывается в моем коде. Однажды, когда pMapping установлен в null (это ставит значение в «size»). Затем память выделяется для новой структуры с использованием этого параметра размера, и функция снова вызывается с использованием указателя на это выделенное пространство памяти для pMapping. (pMapping также имеет указатель на другую структуру, которая также получает некоторое пространство, выделенное за это время).
Вот код старого C++, который достиг этого:
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));
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);
Первоначально я думал, что я не выделяя необходимое количество пространства, поэтому я попробовал старый C++ кода, приведенным выше, и выяснил, что:
sizeof(MAPPING) = 272
and
sizeof(PMAPPINGSECTOR) = 40
Я сделал ту же проверку в моих C# код и нашел следующий:
Marshal.SizeOf(new Mapping()) = 16
and
Marshal.SizeOF(new MappingSector()) = 40
У нас проблема. Структура Mapping должна быть размером 272, но ее единственное 16. Думаю, что я мог бы просто быстро исправить, я вручную выделил 272 вместо 16 здесь, но он все еще ошибся с AccessViolationException.
Любая идея о том, как исправить это? Или что еще может пойти не так?
Я думаю, что это противоречит принципу «Структуры не могут содержать явные без параметров конструкторы» ... – dlchambers