アウトプット枠ではなく一旦コンソールを表示してそこにいろいろと表示したくなることもあることでしょう。
#include <windows.h> #include <string> #include <iostream> #include <fcntl.h> // _O_TEXT #include <io.h> // _open_osfhandle #include "HmCppInvoke.h" using namespace Hidemaru; using namespace std; void SetAllocConsoleStream() { // プロセスにコンソールを割り当てる(ref:A2-1) AllocConsole(); // 現在の std::cout, std::wcout が接続されたストリーム(=FILE*) stream_std_out を開く FILE* stream_std_out = []() { // internal-step-1: // 標準デバイス(=STD_OUTPUT_HANDLE=標準出力を示すフラグ)の"Windowsにおけるハンドル"(=wh_std_out)を取得 auto wh_std_out = GetStdHandle(STD_OUTPUT_HANDLE); // (ref:A2-2) // internal-step-2: // 既存の標準出力のWindowsにおけるハンドル(=wh_std_out)を // CRT(C run-time)のファイル・ディスクリプター(=fd_std_out)として開く // note: このファイル・ディスクリプターをRAII的に閉じる必要はありません (ref:A2-2-a) auto fd_std_out = _open_osfhandle((intptr_t)wh_std_out, _O_TEXT); // (ref:A2-3) // internal-step-3: // 直前に開かれたCRTのファイル・ディスクリプターをCRTのストリーム(FILE*)として開く return _fdopen(fd_std_out, "w"); // (ref:A2-4) }(); // 現在の std::cerr, std::wcerr が接続された stream を開く FILE* stream_std_error = []() { // ↑の cout/wcout と同様 auto wh_std_error = GetStdHandle(STD_ERROR_HANDLE); auto fd_std_error = _open_osfhandle((intptr_t)wh_std_error, _O_TEXT); return _fdopen(fd_std_error, "w"); }(); // 現在の std::cin, std::wcin が接続された stream を開く FILE* stream_std_in = []() { // ↑↑の cout/wcout と同様 auto wh_std_in = GetStdHandle(STD_INPUT_HANDLE); auto fd_std_in = _open_osfhandle((intptr_t)wh_std_in, _O_TEXT); return _fdopen(fd_std_in, "r"); }(); // C++ の標準ストリーム系(iostream系なやつら)を C の標準ストリーム系(cstdio系的なやつら)と同期する std::ios::sync_with_stdio(true); // (ref:A2-5) // 現在のCRTストリームに接続されたCRTハンドルを閉じつつ、新たにCRTストリームへCRTハンドルを接続する freopen_s(&stream_std_out, "CONOUT$", "w", stdout); // (ref:A2-6) freopen_s(&stream_std_error, "CONOUT$", "w", stderr); freopen_s(&stream_std_in, "CONIN$", "r", stdin); } extern "C" __declspec(dllexport) THmNumber test() { Hm.funcDllExport(); //コンソールを作成 FreeConsole(); AllocConsole(); SetAllocConsoleStream(); try { wcout << L"310" << endl; printf("310"); } catch (exception& e) { // エラー内容をchar → wstring へ auto wide_what = Text::Encoding::cp932_to_utf16( e.what() ); Hm.OutputPane.output(wide_what + L"\r\n"); } return 1; }
// DisplayConsole.dllとしてコンパイルした #dll = loaddll(currentmacrodirectory + @"\DisplayConsole.dll"); // 途中でマクロの文法や型の致命的エラーが発生した場合でもdllを解放する。 if (version >= 898) { eval "keepdll #dll, 0"; } #r = dllfuncw(#dll, "test"); freedll(#dll);