Reference 将托管引用(this)传递给非托管代码并调用托管回调

Reference 将托管引用(this)传递给非托管代码并调用托管回调,reference,unmanaged,managed,command-line-interface,Reference,Unmanaged,Managed,Command Line Interface,这是问题的根源。我的答案被删除了,并暗示要开始一个新问题。那么,我们开始吧: 我想将此的托管引用传递给非托管代码。然后从非托管回调中调用托管回调 public ref class CReader 有一个私人领域 private: [...] void *m_pTag; [...] 在托管类的构造函数中,我初始化m_pTag,如下所示: m_pTag = new gcroot<CReader ^>(this); 如果DLL在另一个AppDomain下使用,

这是问题的根源。我的答案被删除了,并暗示要开始一个新问题。那么,我们开始吧:

我想将此的托管引用传递给非托管代码。然后从非托管回调中调用托管回调

public ref class CReader
有一个私人领域

private:
    [...]
    void *m_pTag;
    [...]
在托管类的构造函数中,我初始化
m_pTag
,如下所示:

m_pTag = new gcroot<CReader ^>(this);
如果DLL在另一个AppDomain下使用,则会引发异常。调试器在第行的
gcroot.h
中停止

// don't return T& here because & to gc pointer not yet implemented
// (T should be a pointer anyway).
T operator->() const {
    // gcroot is typesafe, so use static_cast
    return static_cast<T>(__VOIDPTR_TO_GCHANDLE(_handle).Target);
}
//不要在此处返回t&因为尚未实现gc指针(&t)
//(无论如何,T应该是指针)。
T运算符->()常数{
//gcroot是类型安全的,所以请使用static\u cast
返回static_cast(uuu VOIDPTR_u到_GCHANDLE(handle.Target));
}
with
无法跨AppDomains传递GCHandle。

我的问题是,我该怎么办

诚恳地

塞巴斯蒂安

============================编辑====================

我现在能够重现这个问题。我拍了一些截图来展示这个问题

问题是,回调中的struct
gcroot
value
-成员为空

多谢各位

塞巴斯蒂安

============================编辑====================

Puth.

< P> GCROOT C++类是使用GCHANDLE类的包装器。构造函数调用GCHANDLE .ToTutpRE()将句柄转换为不透明指针,一个可以安全地存储为非托管结构或C++类的成员。

随后,转换会使用GCHandle.FromIntPtr()方法将原始指针转换回句柄。Target属性返回托管对象引用

FromIntPtr()确实可能失败,一般异常消息是“无法跨AppDomains传递GCHandle”。此消息仅指出了失败的常见原因,它假定GCHandle在安全代码中使用,只是使用不正确

该消息未涵盖在不安全代码中失败的最常见原因。由于堆损坏,代码总是会因无法诊断的异常而死亡。换句话说,C++类的GCROOT成员或结构被覆盖了任意的值。这当然注定了GCHandle.FromIntPtr()的失败,CLR无法再从垃圾指针值中找到句柄

您可以像诊断任何堆损坏问题一样诊断此错误。您首先要确保获得了良好的复制,以便可靠地触发异常。你是gcroot成员。当成员写入不当时,调试器会自动中断,调用堆栈会让您很好地了解发生这种情况的原因

// don't return T& here because & to gc pointer not yet implemented
// (T should be a pointer anyway).
T operator->() const {
    // gcroot is typesafe, so use static_cast
    return static_cast<T>(__VOIDPTR_TO_GCHANDLE(_handle).Target);
}