3

Visual Studio 2008 と .NET Framework 3.5 を使用して、C++/CLI/.NET フォーム アプリケーションを作成しています。ゲームのエディター。エディター以外のすべてのゲーム コードは純粋な C++ です。アンマネージ コードから呼び出される Forms コードのコールバックが必要なところまで来ています。

GetFunctionPointerForDelegate を使用しています。

まず、 Form クラスに次のものがあります。

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 );

そのため、ポインターを保存し、アンマネージ コードで、別のスレッドからアプリの初期化の早い段階でコールバックを呼び出します。

    // Set up World Object pane in editor to use this map/maptile/etc
    {
        typedef void (*WorldLocCallback)(int, float, float, float, int);
        void* _callback = CEditorUI::UI()->getWorldLocationUpdateCallback();
        int _mapId = charGfxObj->getMapId();
        float _posX = charGfxObj->getPos().x;
        float _posY = charGfxObj->getPos().y;
        float _posZ = charGfxObj->getPos().z;
        int _tileRadius = TILE_RADIUS;
        ((WorldLocCallback)(_callback))( _mapId, _posX, _posY, _posZ, _tileRadius );
    }

アプリケーションを閉じるまで、すべてがアプリで機能的に完全に機能します。呼び出し元のスレッドで常にバッファ オーバーラン エラーが発生し、コール スタックが役に立たなくなります。

editor.exe!__crt_debugger_hook()    Unknown
>editor.exe!__report_gsfailure()  Line 298 + 0x7 bytes  C
editor.exe!__CorExeMain@0()  + 0xe3 bytes   C++

ここでのキッカーは、コールバックが文字通り何もしない場合でもクラッシュすることです。クラッシュを引き起こすために必要なのは、コールバックを呼び出すコードの最後の行を有効にすることだけです。その行を無効にすると、問題はありません。クラッシュは、コールバックを実際に使用するときではなく、終了するときにのみ発生することに注意してください。

試してみるべき推奨事項はありますか?

4

1 に答える 1