C# 如何将 IntPtr 转换回对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/728105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert an IntPtr back into an object
提问by Nick
All, this is a follow up from a previous question here: C# formatting external Dll function parameters
所有,这是上一个问题的后续:C# 格式化外部 Dll 函数参数
Here specifically is the code that I am trying to convert to C#:
这里特别是我试图转换为 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);
The function "FILES_GetMemoryMapping" gets called twice, I'm guessing the first time to get the size of the struct, and the second to actually fill it.
函数“FILES_GetMemoryMapping”被调用两次,我猜第一次是获取结构的大小,第二次是实际填充它。
the "pMapping" is a pointer to a struct in C++, In my C# code, I have pMapping as type IntPtr. The next line I can converted to :
“pMapping”是指向 C++ 中结构的指针,在我的 C# 代码中,我将 pMapping 设为 IntPtr 类型。我可以转换为下一行:
pMapping = Marshal.AllocHGlobal(Marshal.SizeOf(new UM0516.Mapping()));
With (UM0516.Mapping) being the struct. Cool, so I've just allocated some space that IntPtr is pointing to. Now for the next line... "pMapping->NbSectors = 0;"
以 (UM0516.Mapping) 作为结构。很酷,所以我刚刚分配了一些 IntPtr 指向的空间。现在为下一行...“pMapping->NbSectors = 0;”
How am I suppose to go into the now allocated unmanaged memory space, type cast it as a (UM0516.Mapping) struct, and set one of its members? Then make sure i didn't screw with it too much so that the second time I call "FILES_GetMemoryMapping", it can now use this struct??
我该如何进入现在分配的非托管内存空间,将其类型转换为 (UM0516.Mapping) 结构,并设置其成员之一?然后确保我没有过度使用它,以便第二次调用“FILES_GetMemoryMapping”时,它现在可以使用这个结构??
-- Ok, I've taken some advice and now have this:
- 好的,我已经接受了一些建议,现在有了这个:
I tried this and I get a "AccessViolationException was unhandled" exception on the first "FILES_GetMemoryMapping" call
我试过这个,我在第一个“FILES_GetMemoryMapping”调用中得到一个“AccessViolationException was unhandled”异常
Here is what I have:
这是我所拥有的:
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);
Do you think this exception is coming from the "pMapping" parameter? Could this come from anything else that I've passed in?
你认为这个异常来自“pMapping”参数吗?这可能来自我传入的其他任何东西吗?
采纳答案by Adam Robinson
In order to get the IntPtr, what you'll want to do is create your structure, set any options that you may need to, allocate the memory like you already have, then call..
为了获得 IntPtr,您需要做的是创建您的结构,设置您可能需要的任何选项,分配您已有的内存,然后调用..
System.Runtime.InteropServices.Marshal.StructureToPtr(yourStructVariable, pMapping, false);
This will copy the data from your populated structure into your allocated memory.
这会将数据从填充结构复制到分配的内存中。
To copy data from the memory into a new structure named 'mapping
', call...
要将数据从内存复制到名为“ mapping
”的新结构中,请调用...
UM0516.Mapping mapping = (UM0516.Mapping)System.Runtime.InteropServices.Marshal.PtrToStructure(pMapping, typeof(UM0516.Mapping))
回答by John Nunley
To convert an IntPtr back to an object, I used a method that does this:
要将 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 is a list of unfreed GCHandles that are automatically freed when handles is disposed or finialized)
(handles.unfreed 是未释放的 GCHandles 列表,在处理或完成句柄时会自动释放)