[C++] 212 coutデバッグのマクロ化

[M1 Mac, Big Sur 11.6.8, clang 13.0.0]

デバッグの際によく使用するcoutデバッグを簡素化するマクロがネットに公開されていたので早速アレンジしてみました。

以下のヘッダファイルを仕込むことで、DEBUG_MACRO関数により変数を簡単に出力できます。vectorや2次元vectorにも対応しています。変数名に接頭語・接尾語を付けることも可能です。

vector系はPythonにおけるprint関数のように変数名で一括出力できないので、このマクロは重宝しそうです。

#pragma once
#include <iostream>
#include <vector>

#define DEBUG_MACRO(var)  do{std::cout << #var << " : "; view(var);}while(0)
template<typename T> void view(T e){std::cout << e << std::endl;}
template<typename T> void view(const std::vector<T>& v){for(const auto& e : v){ std::cout << e << " "; } std::cout << std::endl;}
template<typename T> void view(const std::vector<std::vector<T> >& vv){ for(const auto& v : vv){ view(v); } }
#include <DEBUG_MACRO.h>

int main(){
    int test1 = 100;
    vector<string> test2 = {"a","b","c"};
    vector<vector<string>> test3 = {{"x1","x2"},{"y1","y2"}};

    DEBUG_MACRO(test1);
    DEBUG_MACRO(test2);
    DEBUG_MACRO(test3);
}
test1 : 100
test2 : a b c 
test3 : x1 x2 
y1 y2 
#pragma once
#include <iostream>
#include <vector>

#define DEBUG_MACRO(var, prefixx, suffixx)  do{std::cout << #prefixx << #var << #suffixx << " : "; view(var);}while(0)
template<typename T> void view(T e) { std::cout << e << std::endl; }
template<typename T> void view(const std::vector<T>& v) { for (const auto& e : v) { std::cout << e << " "; } std::cout << std::endl; }
template<typename T> void view(const std::vector<std::vector<T> >& vv) { for (const auto& v : vv) { view(v); } }

参考サイト

[C++] 209 FLTK : Visual C++への移植 その8 vector要素文字化け

[Windows11, MinGW g++ 9.2.0, Visual C++17, FLTK 1.3.8, Visual Studio 2022]

GUIのタブ内ボタンを押すとアプリが落ちてしまう不具合に対策を施しました。

原因はまたしても文字化けです。要素が日本語のvectorについて文字列比較でインデックス番号を取得しようとしても、文字化けのためできませんでした。

文字化けを解決するとなると泥沼に陥りそうなので、インデックス番号の取得方法自体を変えました。元々が外部関数に頼るという筋の良くない方法ですし、FLTKで適切な関数を見つけるいいタイミングでした。

void getColor(Fl_Widget*, long num) {
    cout << "num " << num << endl;

    Fl_Widget* tab = tabs->value();
    int tab_num = tabs->find(tab);
    cout << "tab_num " << tab_num << endl;

    // 修正前
    // const char* lbl = tab->label();
    // cout << "lbl " << lbl << endl;
    // string lbl_str = (string)lbl;

    // int tab_num = fcs.getIndex(tab_names, lbl_str); // 文字列比較する外部関数
    // cout << "tab_num " << tab_num << endl;

    <以下略>
}

[C++] 208 FLTK : Visual C++への移植 その7 文字化け解決

[Windows11, MinGW g++ 9.2.0, Visual C++17, FLTK 1.3.8, Visual Studio 2022]

GUIの文字化けはプロジェクトの設定で直りました。WindowsプログラミングはまだShift-JISが優勢なのでしょうか。ここまでUTF-8が冷遇されるとは思いませんでした。

一難去って、今度はタブ内のボタンを押すと落ちてしまいます。

Visual Studioのデバッガとしての出番がやってきたようです。

[C++] 207 FLTK : Visual C++への移植 その6 ビルドエラー解消

[Windows11, MinGW g++ 9.2.0, Visual C++17, FLTK 1.3.8, Visual Studio 2022]

ようやくビルドエラーが消えて、exeファイルが生成されました。

その後起動できるようになりましたが、不具合は続いています。

戻り値のデータ型不一致についてはclang++、MinGWでは見逃されていました。VC++の方が厳格というより、他の2つが甘いのではないかと。

[C++] 206 FLTK : Visual C++への移植 その5 libファイル作成完了

[Windows11, MinGW g++ 9.2.0, Visual C++17, FLTK 1.3.8, Visual Studio 2022]

libファイルはまずclコンパイラで作成し、エラーになる場合はVisual Studioで作成しました。

29箇所あったエラーが5箇所まで減り、ようやく移植作業のゴールが見えてきました。これが終わると次はアドオンのプログラミングになります。

[C++] 205 FLTK : Visual C++への移植 その4 clコンパイラでlib, dllファイル作成

[Windows11, MinGW g++ 9.2.0, Visual C++17, FLTK 1.3.8, Visual Studio 2022]

Visual Studioでのlibファイル作成方法にヒントを得て、再度clコンパイラでライブラリ作成を試みたところうまくいきました。静的ライブラリlibと動的ライブラリdllが作成されます。

コマンドは以前のままで、cppファイルとヘッダファイルの関数の先頭に__declspec(dllexport)を付けるだけです。付けないとdllファイルのみ作成になります。

そもそも付けない場合にlibファイル、dllファイル両方作成するのが普通の感覚ではないのかと思ったりしますが、何かとクセが強いMicrosoftですから仕方ないです。

この方法でいけるとなると、Visual Studioでプロジェクトからlibファイル、dllファイルを作成するなんて面倒すぎてやってられません。

日本語まわりの仕様など洗練されているように見えるVisual C++ですが、実際に扱ってみるとなるほど中々の難物でした。まさに隣の芝はなんとやらです。

#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
#include <ctype.h>
#include <memory>

using std::string; using std::vector;
using std::cout; using std::endl;

class Funcs{

public:
__declspec(dllexport) string capitalizeString(string);
__declspec(dllexport) int getIndex(vector<string>&, string);
};
#include "Funcs.h"

__declspec(dllexport) string Funcs::capitalizeString(string s)
{
    vector<char> s_char(s.begin(), s.end());

    vector<char> s_char_up;
    for (auto && c:s_char){
        char c_up = toupper(c);
        s_char_up.push_back(c_up);
    }

    string str(s_char_up.begin(), s_char_up.end());

    return str;
}

__declspec(dllexport) int Funcs::getIndex(vector<string> &input, string searched) {
    for (int i = 0; i < input.size(); i++) {
        if (input[i] == searched) {
            return i;
        }
    }
    return -1;
}
cl /std:c++17 /I"D:\code\VC++\mylib_vc\include" /I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include" ^
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\include" ^
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" ^
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt" ^
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um" ^
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared" ^
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\winrt" ^
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\cppwinrt" ^
/I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\Include\um" ^
"D:\code\VC++\mylib_vc\src\Funcs.cpp" /LD /EHsc /link /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\lib\x64" /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22000.0\\um\x64" /LIBPATH:"D:\code\VC++\mylib_vc\lib"

[C++] 204 FLTK : Visual C++への移植 その3 VSでlib, dllファイル作成

[Windows11, MinGW g++ 9.2.0, Visual C++17, FLTK 1.3.8, Visual Studio 2022]

ライブラリをclコンパイラではなく、Visual Studioでの作成に切り替えました。

今回は静的ライブラリSplit.libと動的ライブラリSplit.dllを作成しました。2時間ほど掛かりました。やはりIDEは勘弁というのが実感です。

Macならコンソールだけでサクッと作れるんですけどね。Windows(Visual Studio)がプログラミングの入口だったら、C/C++ユーザーに成れていたか微妙です。

これでエラー数は1つ減り23箇所になりました。

[C++] 203 FLTK : Visual C++への移植 その2 dllファイル

[Windows11, MinGW g++ 9.2.0, Visual C++17, FLTK 1.3.8, Visual Studio 2022]

カラーアプリMinGW版のVisual C++への移植が遅々として進みません。

コンパイルはクリアしましたが、案の定ビルドで29箇所のエラーに見舞われました。

clコンパイラで作成した自製dllファイルが全て”未解決の外部シンボル”エラーとなり、ライブラリ化はあきらめてcppファイルとしてプロジェクトに追加しています。

コード編集はVSCode、コンパイル&ビルドはVisual Studioと役割分担しています。Visual Studioはエディタとしては使えないです。

dllファイルの変更が完了すれば、エラーはだいぶ減りそうです。