【问题标题】:C++/CLI System.AccessViolationException when calling unmanaged function in managed class在托管类中调用非托管函数时出现 C++/CLI System.AccessViolationException
【发布时间】:2018-10-22 12:55:02
【问题描述】:

我在 C++ 中有一个本机回调函数,让我们这样说:

void ::CallbackFunction(void)
{
  // Do nothing
}

现在我有了另一个原生函数:

void ::SomeNativeFunction(void)
{
  m_callback = std::tr1::bind(&::CallbackFunction, m_Tcy); // save in m_callback | m_Tcy is the class where CallbackFunction exists
  m_Tcy->SomeManagedFunction(m_callback);
}

好的,所以现在我调用了一个托管函数,并给这个函数一个本地 c++ 函数。 让我们看看托管代码:

// This won't work
// typedef std::tr1::function<void __stdcall ()>* callback_function;
typedef std::tr1::function<void()>* callback_function;

callback_function m_nativCallback;

void ::SomeManagedFunction(callback_function callback)
{
  m_nativCallback = callback;
  // Does some stuff that triggers SomeManagedCallback
}

void ::SomeManagedCallback(IAsyncResult^ ar)
{
  (*m_nativCallback)();
}

现在,如果我对此进行调试,我会收到 An unhandled exception of type System.AccessViolationException occurred in .dll Additional information: An attempt was made to read or write in the protected memory. This is an indication that other memory is corrupted. 错误消息。

可能是调用约定有问题吗?

谢谢

【问题讨论】:

  • 如何在代码中使用void ::SomeManagedFunction(callback_function callback)?你传递的callback 是什么?
  • @SlawomirOrlowski 我将::CallbackFunction(void) 作为回调传递。当用户按下上下文菜单按钮时,我使用::SomeManagedFunction。 SomeManagedFunction 然后执行一个函数并需要设置一个回调,以便我知道调用的函数何时完成。

标签: c++ c++-cli


【解决方案1】:

原生部分设置错误:

void ::SomeNativeFunction(void)
{
  m_callback = std::tr1::bind(&::CallbackFunction, m_Tcy); // save in m_callback | m_Tcy is the class where CallbackFunction exists
  //this won't work
  m_Tcy->SomeManagedFunction(m_callback);
}

这对我有用:

void ::SomeNativeFunction(void)
    {
      m_callback = std::tr1::bind(&::CallbackFunction, m_Tcy); // save in m_callback | m_Tcy is the class where CallbackFunction exists
      //this works, even tho the debugger dies on me when I try to debug this
      m_Tcy->SomeManagedFunction(&m_callback);
    }

回调的东西有效,但仍然在本机 main 中出现错误:

First-chance exception at 0x00007ffb2b59dd60 in *.exe: 0xC0000005: Access violation at location 0x00007ffb2b59dd60.
Unhandled exception at 0x00007ffb2b59dd60 in *.exe: 0xC000041D: Exception during a user callback.

此外,我的 Visual Studio 2010 在调试回调时崩溃(在我的 C++/CLI 包装器中)。如果我等待的时间足够长,它会引发以下异常:

Access violation reading location 0xfffffffffffffff8.

【讨论】:

  • 如何在原生类中定义m_Tcy
  • m_tcy 是来自我的 C++/CLI dll 的本地类的共享指针。 m_tcy包含我需要从本机 C++ 访问的 .NET 端的函数。
  • 如果我理解正确的话,m_tcy 的一种类型是本地类,不是托管的,对吧?我认为m_tcy 是对托管类型的引用。
  • 有点复杂。 m_tcy 当然是本机(C++/CLI)类,否则我将无法在本机应用程序中使用它。但是m_tcy 包含一个托管对象(临时包装)。所以调用m_tcySomeManagedFunction 意味着m_tcy 使用它的托管对象来执行函数。
  • 您能介绍一下本机类代码吗?否则很难估计这里有什么问题。我的猜测是垃圾收集器会在运行时移动或删除您的托管内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多