全部,这是上一个问题的后续跟进:C# formatting external Dll function parameters
这里特别是我试图转换为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类型。下一行我可以转换为:
pMapping = Marshal.AllocHGlobal(Marshal.SizeOf(new UM0516.Mapping()));
以(UM0516.Mapping)为结构。很酷,所以我刚刚分配了一些IntPtr指向的空间。现在为下一行...“pMapping-> NbSectors = 0;”
我想如何进入现在分配的非托管内存空间,键入将其转换为(UM0516.Mapping)结构,并设置其中一个成员?然后确保我没有过多地使用它,以便第二次调用“FILES_GetMemoryMapping”时,它现在可以使用这个结构了吗?
- 好的,我已经采取了一些建议,现在有了这个:
我试过这个并且在第一次“FILES_GetMemoryMapping”调用中得到“AccessViolationException未处理”异常
这就是我所拥有的:
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”参数吗?这可能来自我传入的其他任何东西吗?
答案 0 :(得分: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))
答案 1 :(得分: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列表,当句柄被处理或最终化时会自动释放)