2009-04-08 3 views
4

Все это является продолжением из предыдущего вопроса здесь: C# formatting external Dll function parametersКак преобразовать IntPtr обратно в объект

Вот конкретно это код, который я пытаюсь преобразовать в 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)); 

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

Функция «FILES_GetMemoryMapping» вызывается дважды, я предполагаю, что первый раз получить размер структуры, а второй - заполнить ее.

«pMapping» - это указатель на структуру на C++. В моем коде C# у меня есть pMapping как тип IntPtr. Следующая строка I может быть преобразована в:

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

С (UM0516.Mapping) является структурой. Круто, поэтому я просто выделил некоторое пространство, на которое указывает IntPtr. Теперь для следующей строки ... "pMapping-> NbSectors = 0;"

Как я могу предположить, что в настоящее время выделенное неуправляемое пространство памяти, введите его как структуру (UM0516.Mapping) и установите один из его членов? Затем убедитесь, что я не слишком сильно вкрутил его, так что во второй раз я называю «FILES_GetMemoryMapping», теперь он может использовать эту структуру ??

- Хорошо, я взял несколько советов и теперь это:

Я попытался это и я получаю «AccessViolationException было необработанное» исключение на первом «FILES_GetMemoryMapping» называют

Вот что У меня есть:

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); 

Считаете ли вы, что это исключение исходит из параметра «pMapping»? Может ли это исходить из всего, что я прошел?

ответ

10

Для того, чтобы получить IntPtr, что вы хотите сделать, это создать структуру, устанавливать какие-либо параметры, которые, возможно, потребуется, выделить память, как у вас уже есть, то звоните ..

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

Это скопирует данные из вашей заполненной структуры в выделенную вами память.

Чтобы скопировать данные из памяти в новую структуру под названием «mapping», вызов ...

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

Чтобы преобразовать IntPtr обратно в объект, я использовал метод, который делает это:

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 - это список незакрепленных GCHandles, которые автоматически освобождаются, когда ручки расположены или завершены)

Смежные вопросы