【问题标题】:How to convert an IntPtr back into an object如何将 IntPtr 转换回对象
【发布时间】:2010-10-18 04:55:43
【问题描述】:

所有,这是对上一个问题的跟进: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 was unhandled”异常

这是我所拥有的:

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”参数吗?这可能来自我传递的其他任何东西吗?

【问题讨论】:

    标签: c# unmanaged marshalling intptr


    【解决方案1】:

    为了将 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 列表,在释放或完成句柄时会自动释放)

    【讨论】:

      【解决方案2】:

      为了获得 IntPtr,您需要做的是创建结构,设置您可能需要的任何选项,像您已经拥有的那样分配内存,然后调用..

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

      这会将数据从填充的结构复制到分配的内存中。

      要将内存中的数据复制到名为“mapping”的新结构中,请调用...

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

      【讨论】:

        猜你喜欢
        • 2013-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-09
        • 2013-08-12
        • 2010-09-07
        • 2016-12-07
        • 1970-01-01
        相关资源
        最近更新 更多