2

質問を始める前の簡単なメモとして、私は C++ と特に DLL にまったく慣れていません。

現在、プログラムで使用するために、VS2012 で C++ DLL をコーディングしています。特定のプログラムへのソース アクセス権がないことに注意してください。問題のプログラムから何かをするように求められたときに、DLL から別のコンソール ウィンドウに出力を書きたいと思います。

私の質問は、どうすればこのようなことをすることができるでしょうか? 私が望むものを正確に明確にするために、DLLがプログラムに接続されるとすぐに別のコンソールウィンドウが開き、出力がコンソールに書き込まれるようにしたいと思います。DLL がプログラムから切り離されると、コンソール ウィンドウも閉じる必要があります。

これまでの私の推測では、ソリューションで別の Win32 コンソール アプリケーション プロジェクトを作成し、DLL でそれを参照して、そこから特定のメソッドを実行し、呼び出しの引数に含まれる出力を使用するというものでした。特に、この別のコンソール プロジェクトを同じ DLL に含める必要があるため、これについてどうすればよいかわかりません。

ご意見ありがとうございます。

4

2 に答える 2

4

次のクラスでは、何をする必要があるかについてのアイデアが得られます。構築時に、CConsole は AllocConsole を使用してプロセス用の新しいコンソールを作成しようとします。

AllocConsole が失敗した場合、何も変更されません。コンソールは既に存在し、クラスは C ランタイム ハンドルが別の場所に既に設定されていると想定します。

AllocConsole が成功すると、現在 stdout と stdin に関連付けられているオブジェクトが保存され、新しいコンソール用に作成されたオブジェクトに置き換えられます。これで、C ランタイム出力関数 (printf など) が新しいコンソールに出力されます。cout と cin も新しいコンソールを使用します。

RemoveMenu 呼び出しは、ユーザーがコンソール ウィンドウを閉じるのを防ぎ、プロセスを終了します。この機能以外は必要ありません。

CConsole が破棄されると (そして AllocConsole が成功すると)、stdout と stdin が復元され、FreeConsole への呼び出しでコンソールが閉じられます。

コンソールを作成した機能を超えてコンソールを存続させたい場合、このクラスは不便だと思います。新しい CConsole を取得し、削除で閉じるまでそのポインタを追跡する必要があります。ただし、その実装では、独自のプロジェクトで実行する必要がある手順が示されています。dll でこれを試したことはありませんが、これが問題になる理由はわかりません。

Console.h:

#pragma once
#include <stdio.h>

class CConsole {
    FILE m_OldStdin, m_OldStdout;
    bool m_OwnConsole;
public:
    CConsole();
    ~CConsole();
};

Console.cpp:

#include <windows.h>
#include <conio.h>
#include <FCNTL.H>
#include <io.h>
#include "Console.h"

static BOOL WINAPI MyConsoleCtrlHandler(DWORD dwCtrlEvent) { return dwCtrlEvent == CTRL_C_EVENT;}

CConsole::CConsole() : m_OwnConsole(false) {
    if(!AllocConsole()) return;

    SetConsoleCtrlHandler(MyConsoleCtrlHandler, TRUE);
    RemoveMenu(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE, MF_BYCOMMAND);
    const int in  = _open_osfhandle(INT_PTR(GetStdHandle(STD_INPUT_HANDLE)),  _O_TEXT);
    const int out = _open_osfhandle(INT_PTR(GetStdHandle(STD_OUTPUT_HANDLE)), _O_TEXT);
    m_OldStdin  = *stdin;
    m_OldStdout = *stdout;

    *stdin  = *_fdopen(in,  "r");
    *stdout = *_fdopen(out, "w");

    m_OwnConsole = true;
}

CConsole::~CConsole() {
    if(m_OwnConsole) {
        fclose(stdout);
        fclose(stdin);
        *stdout = m_OldStdout;
        *stdin  = m_OldStdin;
        SetConsoleCtrlHandler(MyConsoleCtrlHandler, FALSE);
        FreeConsole();
    }
}

楽しみ!

于 2013-05-14T08:51:16.397 に答える