由于.NET值类型(管理C ++结构)被存储在堆栈为什么它(或者是它实际上)必要pin_ptr它们以便将指针传递到一个非托管函数?
例如。 BYTE B [100];
如果我通过&B非托管函数没有第一固定的话,可能堆栈损坏?
是CLR堆栈主题以同样的方式为GC堆改变? 导致我相信CLR堆栈使用不同寻常的优化,比如使用,这使得它不适合用作缓冲非托管功能的处理器的寄存器。 关于栈上钉扎值类型的规则似乎是不清楚。
我注意到什么,似乎这样的内核NTDLL功能NtfsControlFile发送缓冲区数组时会有一些腐败现象。 钢钉值类型解决了这个问题。 但从来没有通过API调用。
这难道不是因此,从根本上不安全通过任何指针的任何值类型的堆栈任何非托管功能上,没有第一固定呢?
你是正确的, BYTE b[100];
是本地栈上创建的,因此不会受到托管堆中移动等,但我相信你的问题是一个简单的C ++的错误。
你说,
如果我通过&B非托管函数没有第一固定的话,可能堆栈损坏?
你不应该使用地址运算符(&)阵列名称(二)由于本身数组名已经是阵列的起始地址。 使用&b
将无法正常工作,而产生的行为将取决于多种因素(如编译器和它的设置)。
简单地说,你应该只在数组名传递数组名(B)而不是使用地址运算符(&B)调用函数时。
顺便说一句,我相信你问一个人是否可以叠到本机的功能上传递一个托管值类型没有第一固定它,因为你给的例子问题混淆的是,通过非托管的,基于堆栈的本地阵列类型,无关与托管值类型。
是的,内存管理是能够切换地址,它只是更新自己的内部对它们的引用。 只要你潜水管理层之下,你必须确保你用是被移动到另一个位置安全工作的指针。 使用pin_ptr的告诉内存管理器独自离开了这块内存。
这难道不是因此,从根本上不安全通过任何指针的任何值类型的堆栈任何非托管功能上,没有第一固定呢?
是。
这是由于GC删除/异步移动到您的方法。
见动GC为CLR的GC是如何工作的描述。
据我可以告诉这一切是指在GC堆对象。
关键是我这里指的是专门堆栈存储器。
我已经发布,这似乎表明,堆栈内存的API调用传递堆栈存储器作为缓冲过程中被损坏的例子: http://social.msdn.microsoft.com/Forums/en-US/clr/thread/3779c1ee- 90b8-4a6a-9b14-f48d709cb27c
如果堆栈内存需要寄托,那么这似乎打破的“它就可以工作”的理念。 在非托管C ++中,我们可以声明一个堆栈缓冲器,然后一个指向它的指针传递给API函数。 然而,如果移动到托管代码需要被固定,它似乎从根本上动摇“它只是工作”。
这是混淆MSDN文档为pin_ptr怎么好像说这只是防止移动的物体但是它也有可能销值类型这似乎是在堆栈上,不应该反正移动。
我专门养的堆栈存储器是否在处理托管或非托管代码的方式的问题。 当MSIL调试我发现它无法查看堆栈并没有堆栈浏览器的工具这一点。 我听说过,但我不知道,没有“真正的”栈MSIL,取而代之的是虚拟机CLR是免费的优化,例如使用免费的处理器寄存器,而不是实际的内存。 目前还不清楚这是否是真实的,而且,它是否适用于堆栈中的参数传递,或堆在局部变量的内存。
在上述示例项目奇数效果是,腐化对象上pin_ptr似乎以固化的问题。 然而,对象是在栈上,不应该需要牵制。 难道说在/ CLR解释pin_ptr不只是“不动这个对象”,而且还“离开这个区域作为真正的记忆,不要试图注册在它的优化”,这将导致它保持纯洁的销的持续时间?
我特别想知道,如果/ CLR是足够聪明的说避免到API的调用期间其在法堆栈内存的优化,但将可能不给我在上面的例子一样恩典由于直接装载NTDLL和方式的函数声明为一个typedef。
我曾考虑增加编组属性功能类型定义,但似乎未能如愿。 我注意到有没有MarshallAs上WinAPI的DEFS属性。
我已成功地打入上述使用__debugbreak项目()之前的NTDLL通话然而,这只是给了我似乎无法步入本机代码托管调试模式。 我不会写“ASM INT 3”,因为64不支持它。 我所看到的,但是,出错的价值NumberOfPairs在一个内存位置传递指向一个寄存器,而不是作为一个注册。