c# - pin_ptr 无法在非托管类中声明托管对象

标签 c# c++-cli interop

我有非托管类。在那个类中,我有一个托管对象。现在我想要一个 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/

相关文章:

c# - 互操作:结构成员名称与 c# 关键字冲突 - 事件

c# - Exchange Web 服务 API 和 401 未授权异常

visual-c++ - vector<int> - 缺少类型说明符

c# - C++CX 与 C++CLI - 是否可以从 C++CX 动态程序集访问动态 WUP C# dll?

c# - 在C#程序中访问linux文件系统

c# - 将 .NET ArrayList 编码到 VB6 [Com interop]

c# - 在 C# 中验证 TreeView 拖/放操作的最佳方法

c# - NUnit 在汇编中找不到测试

c# - 缺少命名空间或程序集引用时出错

c++ - 我是否需要显式释放托管 C++ 中的内存?