我有非托管类。在那个类中,我有一个托管对象。现在我想要一个 pin_ptr 用于我的非托管类中的托管对象。当我尝试执行此操作时,出现此错误“错误 C3265:无法在非托管 ProjectWrapper
中声明托管 _pinnedProject
我该如何实现?
这是代码。
class ProjectWrapper
{
private:
msclr::auto_gcroot<Project^> _project; // --> This works fine,
pin_ptr<msclr::auto_gcroot<Project^>> _pinnedProject; // ---> This gives error
public:
ProjectWrapper()
{
_project = gcnew Project();
pin_ptr<msclr::auto_gcroot<Project^>> anotherPinnedProject = &_project; // --> This one works,
//_pinnedProject = _project; // --> I want to use this instead of above live,
}
}
最佳答案
关于 pin_ptr<>
的 MSDN 文章并不羞于告诉你为什么这行不通:
Pinning pointers can only be declared as non-static local variables on the stack.
Pinning pointers cannot be used as:
function parameters
the return type of a function
a member of a class
the target type of a cast.
这是有充分理由的,这种对象固定非常有效。它根本不需要显式调用 CLR,当垃圾收集器遍历堆栈寻找根时,就会发现该 pin。这要求对象引用是局部变量,编译器在 MSIL 中使用 [pinned] 属性发出它。还使用 fixed 关键字在 C# 语言中公开。
所以,这是不可能的,也不应该追求这个。长时间固定一个对象对 GC 非常不利,它是路上的一 block 石头,会阻止堆段被回收。您应该只在需要指针稳定的确切时刻固定,那个时刻只发生在使用指针的函数代码中。
如果你想解决这个问题,那么你需要回到大头针上。这需要 GCHandle::Alloc() ,传递 GCHandleType::Pinned。您从 AddrOfPinnedObject() 获取所需的指针,使用 Free() 方法释放。
关于c# - pin_ptr 无法在非托管类中声明托管对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28541452/