41

AllocConsole() と cout を使用してデバッグ目的でデータを表示する DLL があります。
以前は正常に動作していましたが、コンパイラ (Visual Studio 2012) を最新のものに更新したため、dll はコンソールのみを表示し、prints/couts は表示しません。
なぜこれが起こっているのか、私にはわかりません。
何か案は?

私のコードの一部

__declspec(dllexport) INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
    switch(Reason)
    {
    case DLL_PROCESS_ATTACH:    
        AllocConsole();

        DisableThreadLibraryCalls(hDLL);

        //
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)pSend, MySend);
        if(DetourTransactionCommit() == NO_ERROR)
             cout << "[" << MySend << "] successfully detoured." << endl;

しかし、何も表示されません。

4

3 に答える 3

87

stdout をコンソールにリダイレクトする必要があるかもしれないことを漠然と思い出しました。私は間違っているかもしれません (あなたのコードは以前に動作していたので):

AllocConsole();
freopen("CONOUT$", "w", stdout);
std::cout << "This works" << std::endl;
于 2013-03-21T12:34:56.843 に答える
23

を介して新しいコンソールを割り当てた後AllocConsole()、標準ストリーム ( stdoutstderrstdin) を使用する前に再度開く必要があります。

を使用してこれを行うことができますfreopen(Visual Studio の新しいバージョンでは、使用する必要がありますfreopen_s) 例:

FILE *fDummy;
freopen_s(&fDummy, "CONIN$", "r", stdin);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
freopen_s(&fDummy, "CONOUT$", "w", stdout);

非推奨を使用する場合は、 ingで警告を無効にすることfreopenができます。#define_CRT_SECURE_NO_WARNINGS

ワイド文字ストリーム ( std::wcout、など) も使用する場合は、 を呼び出してプロセスの新しい出力ハンドルを設定するstd::wcerr必要があります。/をファイル名として呼び出すことでSetStdHandle()、これに必要なファイル ハンドルを取得できます。CreateFile()CONOUT$CONIN$

HANDLE hConOut = CreateFile(_T("CONOUT$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SetStdHandle(STD_OUTPUT_HANDLE, hConOut);

さらに、ストリームを再度開く前にストリームの 1 つを使用しようとすると、それらの に と がstd::ios_base::badbit設定std::ios_base::failbit されるiostateため、その後の書き込み/読み取りは無視されます。
でストリームの状態をリセットでき.clear()ます。その後、ストリームの読み取り/書き込みを再度行うことができます。

std::cout.clear();
std::cin.clear();

後にすべてのストリームを再度開く完全な例を次に示しますAllocConsole()

void CreateConsole()
{
    if (!AllocConsole()) {
        // Add some error handling here.
        // You can call GetLastError() to get more info about the error.
        return;
    }

    // std::cout, std::clog, std::cerr, std::cin
    FILE* fDummy;
    freopen_s(&fDummy, "CONOUT$", "w", stdout);
    freopen_s(&fDummy, "CONOUT$", "w", stderr);
    freopen_s(&fDummy, "CONIN$", "r", stdin);
    std::cout.clear();
    std::clog.clear();
    std::cerr.clear();
    std::cin.clear();

    // std::wcout, std::wclog, std::wcerr, std::wcin
    HANDLE hConOut = CreateFile(_T("CONOUT$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    HANDLE hConIn = CreateFile(_T("CONIN$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    SetStdHandle(STD_OUTPUT_HANDLE, hConOut);
    SetStdHandle(STD_ERROR_HANDLE, hConOut);
    SetStdHandle(STD_INPUT_HANDLE, hConIn);
    std::wcout.clear();
    std::wclog.clear();
    std::wcerr.clear();
    std::wcin.clear();
}
于 2019-07-28T14:48:27.710 に答える