1

この質問は、グローバル オブジェクトから main 関数を呼び出すことができないことを除いて、私が以前に尋ねた質問のように見えます。したがって、このコードはメインでは機能しません。しかし、他の関数でも失敗するのはなぜですか?

これがコードです。

.exe
main.cpp

#include "dll_class.h"
#include <iostream>
int my_main(void)
{
    std::cout << "Enter the my_main code.\n";
    std::getchar();
}

DllClass object(my_main);
int main(void)
{
    std::cout << "Enter the main code.\n";
    std::getchar();
}

.dll
dll_class.h

#include "platform.h"
#include <iostream>
class DLL_API DllClass //DLL_API is just a macro for import and export.
{
public:
    DllClass(int(*main)(void))
    {
        std::cout << "Start application.\n";
        platform = new Platform(main);
    }
    ~DllClass(void)
    {
        delete platform;
    }
private:
    Platform* platform;
};

platform.h

class DLL_API Platform
{
public:
    Platform(main_t main_tp);
    ~Platform(void){}
};

プラットフォーム.cpp

#include "platform.h"
#include "Windows.h"
#include <iostream>

HHOOK hookHandle;
int(*main_p)(void);//This will hold a the main function of the the .exe.
LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam);

DWORD WINAPI callMain(_In_  LPVOID lpParameter)
{
    std::cout << "Calling the main function.\n";
    main_p();
    return 0;
}

Platform::Platform(int(*main_tp)(void))
{
    main_p = main_tp;
    CreateThread(NULL, 0, callMain, NULL, 0, NULL);
    std::cout << "Setting hooks.\n";
    hookHandle = SetWindowsHookEx(WH_MOUSE_LL, keyHandler, NULL, 0);
    std::cout << "Enter message loop.\n";
    MSG message;
    while(GetMessage(&message, (HWND)-1, 0, 0) != 0){
        TranslateMessage( &message );
        DispatchMessage( &message );
    }
}

LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam)
{
    std::cout << "Inside the hook function.\n" << std::endl;
    return CallNextHookEx(hookHandle, nCode, wParam, lParam);
}

ある瞬間まで、それはうまくいきます。これが出力です。

Start application.  
Setting hooks.  
Calling the main function.  
Enter message loop.  
Inside the hook function. (A lot of times of course).  

しかし、それは決して言いません:

Enter the my_main code.
Enter the main code.

dllにexe関数を呼び出させることは不可能ですか?

4

2 に答える 2

1

答えは、私があなたの他の質問に与えたものと同じです。コンストラクPlatformターがハングしています。ループ終了条件が満たされないため、コンストラクターは戻りません。また、mainすべてのグローバル オブジェクトが構築されるまで、関数は実行できません。

更新:上記の議論は、Enter the main code印刷されない理由です。

my_main関数をステップ実行すると、次の問題が表示されます。とEnter the my_main codeの呼び出しは無視されます。これは、異なる翻訳単位でのグローバル オブジェクトの構築順序が指定されていないためです。メインの実行可能ファイルでは、グローバル オブジェクトが最初に構築されます。これは、およびオブジェクトが完全に構築されない可能性があることを意味します。それが印刷できない理由であり、なぜ読むことができないのかです。coutgetcharobjectcincoutcoutgetchar

于 2013-03-09T15:51:35.207 に答える
1

確かに、ここで行うべき正しいことは、object内部を構築することmainです。必要に応じて、オブジェクトに渡しmy_mainます。しかし、これは「構築される前に何かを使用しようとする」ことをすべて解決します。

ここでの重要な点 (他の回答のコメントを読んでのみ収集したもの) は、coutオブジェクトがメインの実行可能ファイルと DLL で「同じもの」ではないということです。coutこれは、入力する前に行うことを呼び出す際の問題につながりますmain[前の質問でも説明しようとしました - C ランタイム ライブラリは特定のものを初期化する必要があり、それは呼び出される前に不特定の順序で発生しますmain]。

于 2013-03-09T17:43:18.120 に答える