C++ cli 使用Marshal::GetFunctionPointerForDelegate并从非托管代码调用回调会在退出应用程序时导致缓冲区溢出

C++ cli 使用Marshal::GetFunctionPointerForDelegate并从非托管代码调用回调会在退出应用程序时导致缓冲区溢出,c++-cli,unmanaged,buffer-overrun,C++ Cli,Unmanaged,Buffer Overrun,我正在使用Visual Studio 2008和.NET Framework 3.5,并制作一个C++/CLI/.NET窗体应用程序;游戏的编辑。除了编辑器之外,所有游戏代码都是纯C++的。我需要从非托管代码调用表单代码中的回调 我正在使用GetFunctionPointerForDelegate 首先,我在我的表格课上有: public: delegate void ADelegate(Int32, float, float, float, Int32); public: static ADe

我正在使用Visual Studio 2008和.NET Framework 3.5,并制作一个C++/CLI/.NET窗体应用程序;游戏的编辑。除了编辑器之外,所有游戏代码都是纯C++的。我需要从非托管代码调用表单代码中的回调

我正在使用GetFunctionPointerForDelegate

首先,我在我的表格课上有:

public: delegate void ADelegate(Int32, float, float, float, Int32);
public: static ADelegate^ delegateInstance;
然后我在表单构造函数中设置回调:

        // Set up World Objects callback
        typedef void (__stdcall *WorldLocationUpdateCallback)(Int32, float, float, float, Int32);
        WorldLocationUpdateCallback _callback;

        // Create an instance of a delegate, using GetFunctionPointerForDelegate
        delegateInstance = gcnew ADelegate( this, &MainForm::InitWorldObjectPane );

        // Convert the delegate to a pointer
        IntPtr anIntPtr = Marshal::GetFunctionPointerForDelegate( delegateInstance );

        // Cast the pointer into a function pointer
        _callback = static_cast<WorldLocationUpdateCallback>(anIntPtr.ToPointer());

        CEditorUI::UI()->setWorldLocationUpdateCallback( (void*)_callback );
在我关闭应用程序之前,我的应用程序在功能上一切都很完美。它总是随着调用线程中的缓冲区溢出错误而消亡,调用堆栈对此毫无帮助:

editor.exe!__crt_debugger_hook()    Unknown
>editor.exe!__report_gsfailure()  Line 298 + 0x7 bytes  C
editor.exe!__CorExeMain@0()  + 0xe3 bytes   C++
这里的关键是,即使回调实际上什么都不做,它也会崩溃。我要做的就是启用调用回调的最后一行代码。禁用该线路后,没有问题。请记住,崩溃只发生在退出时,而不是在实际使用回调时


有什么可以尝试的建议吗?

在花了一整天的时间来处理这个问题并搜索其他相关的东西之后,我多少解决了这个问题,以防其他人有这个问题

将委托声明移到类外并用以下内容装饰它:

[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)] 

…帮我解决了。显然,cdecl的堆栈清除效果解决了溢出问题。

非常感谢您,我花了3天多的时间试图确定这一点。当GC在我的托管代码中运行时,我会得到一个堆栈溢出。我有一个管理C++类,包包一个非托管类设置回调。如您所述装饰回调解决了问题
[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]