[C++] 190 Windows11での開発環境構築 Make for Windows他

[Windows11, g++ 9.2.0, NO IDE]

Windows11でFLTKアプリを開発できる環境を構築していきます。ブラックボックス嫌いの非IDE派なので、基本Visual Studioは使いません。

g++コンパイラは以前MinGW版をインストールしていたのでそのまま使います。GDBデバッガも同梱されています。

次にMake for Windowsをインストールしてから、Makefileの内容をWindows仕様に書き換えます(rmコマンド→delコマンドなど)。Macから持ってきたコードはShift-JISに変換して使います。

これでMakefileを使ったHello Worldを実行できるようになりました。Macの時の癖でつい実行ファイルをダブルクリックしてしまいます。Windowsの場合はコマンドプロンプトにファイル名を入力して実行します。

続いてFLTKのインストールですが、次回以降記事にします。

# コンパイラ設定
COMPILER = g++
DEBUG = -g

# オプション設定
CPPFLAGS = -std=c++11

LDFLAGS =

# includeパス(-I)
INCLUDE = 

# ライブラリパス(-l)
LIBRARY_l = 

# ライブラリパス(-L)
LIBRARY_L = 

# ソースファイル
SRCDIR = .
SRCS = test.cpp

# オブジェクトファイル
OBJDIR = .
OBJS = test.o

# 実行ファイル
TARGETDIR = .
TARGET = test
	
# cppファイルからoファイル作成 $<:依存ファイル
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
	$(COMPILER) $(CPPFLAGS) $(INCLUDE) $(DEBUG) -o $@ -c $<

# oファイルから実行ファイル作成
$(TARGET):$(OBJS)
	$(COMPILER) -o $(TARGETDIR)/$@ $(OBJS) $(LIBRARY_l) $(LIBRARY_L) $(LDFLAGS)

# 全ソース・コンパイル&ビルド
.PHONY:all
all: clean $(OBJS) $(TARGET)

# oファイル・実行ファイル削除
.PHONY:clean
clean:
	del /Q $(OBJS) $(TARGET)

[C++] 189 FLTK : カラーアプリ ボタン空押し対応

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, FLTK 1.3.8, NO IDE]

カラーアプリC++版へのMicrosoft Store更新に向けデバッグを実施しました。

ボタンの空押しで未入力なのに色が表示されたり、アプリが落ちるケースがありましたので、モーダルダイアログを表示するようにしました。

最近LLDBデバッガを積極的に使い始め、レジスタやメモリへの書き込み内容を意識するようになった効果なのか、やみくもに取り組んでいた以前とは違って気持ちに余裕が出てきました。

何かしらの不具合があっても最悪LLDBを使えば何が起こっているのか正確につかめるので、どっしり構えられるようになりました。異常終了時に表示されるAppleレポートの詳細を調べることが可能です。

アセンブリ言語まで細分化すれば、LLDBがまともである限りCPUとRAMメモリの挙動はほぼ把握できます。

void showColor(Fl_Widget*, void*){
	onoff_zero = zero_rbtn->value();
    onoff_sharp = sharp_rbtn->value();
    onoff_hex = hex_rbtn->value();
    onoff_rgb = rgb_rbtn->value();

    input_code = code_input->value();
    if (input_code == ""){
        const char* msg = "カラーコードを入力してください";
        dlg = new modalDialog(400, 200, "Attention", msg);
        dlg->hotspot(window);

        int x_win = window->x_root();
        int y_win = window->y_root();
        cout<<"x_win "<< x_win <<" y_win "<< y_win <<endl;

        dlg->resize(x_win+205, y_win+165,250,150);
        dlg->set_modal();
        dlg->show();

        return;
    }
    
    if (onoff_zero == 1){
        ToZeroConvert();
    } else if (onoff_sharp == 1){
        ToSharpConvert();
    } else if (onoff_hex == 1){
        ToHexConvert();
    } else {
        ToRgbConvert();
    }

    selectColorListAdd();
}

[C++] 188 FLTK : カラーアプリC++版への入れ替え 

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, FLTK 1.3.8, NO IDE]

久しぶりにMicrosoft Storeのデータを確認すると、少ないながらもカラーアプリの取得数が増えていました。

アニメなどを通して日本の色彩文化に興味を持っている方々と推察しますが、日本語版と英語版しかないためか、西欧の割合が極端に少ないです。あるいは、ただ単に日本への興味が薄いのでしょうか。

日本が25%でアジア・北米・東欧が同率で続き、その次が北欧でした。なぜかヨーロッパでも西欧以外でチェックされています。英語への抵抗が少ないということかもしれません。

ストアにアップしているのはJava・Swing版なのでブラッシュアップ済みのC++版へ入れ替えを進めていきます。

[C++] 187 FLTK : SFTP補助アプリ マウント解除 Fl_Light_Button

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, FLTK 1.3.8, NO IDE]

WindowsPCとSMB接続した場合は共有フォルダがマウントされるため、Fl_Light_Buttonを使ってマウント解除できるようにしました。

Fl_Toggle_Buttonでもよかったのですが、押しっぱなしになった時の色を設定できないので、ボタンの一部ながら色を自由に選べるFl_Light_Buttonを選択しました。

これでFinderを一切触らずにファイル転送できます。

Fl_Light_Button *umnt_btn;
int choice_num;
int mount = 0; // マウント状態
string cmd_unmount;

void conn_cb(Fl_Widget*, void*) {
    string cmd_conn;

    choice_num = choice -> value();
    switch(choice_num){
        case 0:{
            cmd_conn = "sftp xxx.local"; // Mac mini Intel
            break;
        }
        case 1:{
            cmd_conn = "sftp xxx.local"; // MacBook Air M1
            break;
        }
        case 2:{
            cmd_conn = "sftp xxx.local"; // MacBook Intel
            break;
        }
        case 3:{
            mount = 1;
            umnt_btn -> value(1);
            cmd_conn = "mount_smbfs //[ユーザ名]@192.168.xx.x/share /Users/[ユーザ名]/share"; // WindowsPC
            cmd_unmount = "umount /Users/[ユーザ名]/share";
            break;
        }
        case 4:{
            cmd_conn = "sftp xxx.local"; // LinuxPC
            break;
        }
    }

    cout << "cmd_conn " << cmd_conn << endl;

    conn_input -> value("");
    conn_input -> value(cmd_conn.c_str());

    // クリップボードにコピー
    string cmdConnCopy = "echo '" + cmd_conn + "' | LANG=ja_JP.UTF-8 pbcopy";
    output_line -> insert(cmdConnCopy.c_str());
    output_line -> insert("\n");
    system(cmdConnCopy.c_str());
}

void umnt_cb(Fl_Widget*, void*) {
    if (mount == 1){
        system(cmd_unmount.c_str());
        mount == 0;
    }
}

// main関数内
umnt_btn = new Fl_Light_Button(295,110,50,25,"MNT");
    umnt_btn->color(fl_rgb_color(112,128,144));
    umnt_btn->labelcolor(fl_rgb_color(255,239,213));
    umnt_btn->selection_color(fl_rgb_color(248,184,98)); // ON時のボタンの色
    umnt_btn->labelsize(14);
    umnt_btn->callback(umnt_cb);

[C++] 186 FLTK : SFTP補助アプリ SMBの一部導入

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, FLTK 1.3.8, NO IDE]

MacとWindows11間のファイル移動に使用していたOpenSSHサーバが突然使えなくなり、復旧もできないのでSMBに変更しました。

mount_smbfsファイルはsbinディレクトリにあり、.bash_profileなどでパスを通しておく必要があります。

Mac-Mac間、Mac-Linux間はこれまで通りSFTPを使います。

OpenSSHサーバについてはWindows11関連のネット情報がほぼ皆無で本当に使えるのかどうか疑問ではあります。

時たまイジるWindows11は本当に使いにくく、Windows Vista、Windows8以来の失敗作という評価が私の中で固まりつつあります。Windows3.1以降では最悪だと思います。大変でしょうが、次世代OSの開発を急いでもらいたいものです。

extern char *dirName;

void conn_cb(Fl_Widget*, void*) {
    string cmd_conn;
    string pc;

    choice_num = choice -> value();
    switch(choice_num){
        case 0:{
            pc = "xxx.local"; // Mac mini Intel
            break;
        }
        case 1:{
            pc = "xxx.local"; // MacBook Air M1
            break;
        }
        case 2:{
            pc = "xxx.local"; // MacBook Intel
            break;
        }
        case 3:{
            pc = "mount_smbfs //[ユーザ名]@192.168.xx.x/share /Users/[ユーザ名]/share"; // WindowsPC
            break;
        }
        case 4:{
            pc = "xxx.local"; // LinuxPC
            break;
        }
    }

    if (choice_num != 3){
        cmd_conn = "sftp " + pc;
    } else {
        cmd_conn = pc;
    }
    cout << "cmd_conn " << cmd_conn << endl;

    conn_input -> value("");
    conn_input -> value(cmd_conn.c_str());

    string cmdConnCopy = "echo '" + cmd_conn + "' | LANG=ja_JP.UTF-8 pbcopy";
    output_line -> insert(cmdConnCopy.c_str());
    output_line -> insert("\n");
    system(cmdConnCopy.c_str());

}

void cmd_cb(Fl_Widget*, void*) {
    string cmd0;
    string cmd1;
    string cmd;

    int onoff_put = put_rbtn->value();
    int onoff_dir = dir_rbtn->value();

    if (choice_num != 3){
        if (onoff_put == 1){
            cmd0 = "put";
        } else {
            cmd0 = "get";
        }
    } else {
        if (onoff_put == 1){
            cmd0 = "cp";
        } else {
            cmd0 = "cp";
        }
    }

    if (onoff_dir == 1){
        cmd1 = "-r";
    } else {
        cmd1 = "";
    }

    const char* fileName = file_input -> value();
    const char* toName = to_input -> value();

    if (choice_num != 3){
        cmd = cmd0 + " " + cmd1 + " \"" + string(fileName) + "\" " + string(toName);
    } else {
        if (onoff_dir == 1){
            cmd = cmd0 + " " + cmd1 + " \"" + string(fileName) + "\" /Users/[ユーザ名]/share/" + dirName;
        } else {
            cmd = cmd0 + " " + cmd1 + " \"" + string(fileName) + "\" /Users/[ユーザ名]/share";
        }
    }
    cout << "cmd " << cmd << endl;

    cmd_input -> value("");
    cmd_input -> value(cmd.c_str());

    string cmdCopy = "echo '" + cmd + "' | LANG=ja_JP.UTF-8 pbcopy";
    output_line -> insert(cmdCopy.c_str());
    output_line -> insert("\n");
    system(cmdCopy.c_str());

}

[C++ & Python] 185 FLTK : LLDB補助アプリの製作着手

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, Python 3.10.4, NO IDE]

早いもので前作のビデオツールアプリ完成から20日ほど経過していました。

LLDBから得られたレジスタやメモリのデータをExcelにまとめるツールを作ることにしました。逆アセンブリコード1行ごとのレジスタ値、スタック領域メモリ値を一気にまとめます。

C++とPythonで作成します。役割分担は以下の通りです。

C++ : GUI(FLTK)、LLDBコマンド作成・実行・ログ取得
Python : LLDBログから各データを抽出しExcelファイルにまとめる

まずはPythonから取り組みます。

LLDBログデータ例

[C++] 184 C++ & アセンブラ用Makefile

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, NO IDE]

簡単なコードをアセンブリ言語で書くためのMakefileを作成しました。

cppファイルからsファイルに変換して叩き台にすることもできますし、sファイルを一から書くことも可能です。

きょうびアセンブリ言語を使うのは命令セットの探索やインラインアセンブラなど一部の用途を除いて酔狂でしかないでしょう。

# コンパイラ設定
COMPILER = clang++
DEBUG = -g

# オプション設定
CPPFLAGS = -std=c++17

# includeパス(-I)
INCLUDE = -I./include -I/Volumes/DATA_m1/code/cpp/mylib/include

# ソースファイル
SRCDIR = ./src
SRCS = $(shell find $(SRCDIR) -type f)

# アセンブリファイル
ASMDIR = ./asm
ASMS = $(addprefix $(ASMDIR), $(patsubst ./src/%.cpp,/%.s,$(SRCS)))

# オブジェクトファイル
OBJDIR = ./obj
OBJS = $(addprefix $(OBJDIR), $(patsubst ./src/%.cpp,/%.o,$(SRCS)))

# 実行ファイル
TARGETDIR = ./bin
TARGET = test

# $<:元ファイル $@:作成ファイル

# cppファイルからsファイル作成
$(ASMDIR)/%.s: $(SRCDIR)/%.cpp
	$(COMPILER) $(CPPFLAGS) $(INCLUDE) $(DEBUG) -fno-pic -fomit-frame-pointer -S $<
	mv *.s $(ASMDIR)

# sファイルからoファイル作成
$(OBJDIR)/%.o: $(ASMDIR)/%.s
	$(COMPILER) -o $@ $< -c

# oファイルから実行ファイル作成
$(TARGET):$(OBJS)
	$(COMPILER) -o $(TARGETDIR)/$@ $(OBJS)

# ビルド(実行ファイル作成)
.PHONY:tar
tar: $(TARGET)

# cppファイルからsファイル作成
.PHONY:asm
asm: $(ASMS)

# sファイルからoファイル作成
.PHONY:obj
obj: $(OBJS)

# oファイル・実行ファイル削除
.PHONY:clean
clean:
	rm -rf $(OBJS) $(TARGETDIR)/$(TARGET)

[C++] 183 FLTK : 動画を結合する FFmpeg

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, FLTK 1.3.8, NO IDE]

ビデオツールアプリに動画を結合する機能を実装しました。

これで簡単な編集であればこのアプリで済ませることができるようになりました。

アプリ搭載機能
1.動画からサイズ、時間、フレームレートなどメタ情報を取得する
2.動画を各フレームに切り出す(静止画としても利用可)
3.指定したフレームから動画を作成する
4.動画にぼかしを入れる(FFmpegライブラリやハードが許す限り何ヶ所でも)
5.動画を結合する

string listFile = "list.txt";
string concatFile = "concat.txt";

void concatCB(Fl_Widget*, void*){
    // LIST欄の文字列をテキストファイル化
    const char* list = list_input -> value();
    cout << "list "  << list << endl;

    std::ofstream file;
    file.open(listFile, std::ios::out);
    file << string(list) << endl;
    file.close();

    const char* output = out3_input -> value();
    string cmd = "/opt/homebrew/Cellar/ffmpeg/5.1/bin/ffmpeg -f concat -safe 0 -i " + listFile + " -c copy " + string(output) +  " 2>" + concatFile;
    cmdBuffer2 -> append(cmd.c_str());
    cmdBuffer2 -> append("\n");
    cout << "cmd: "<< cmd << endl;

    // cmdTextDisplay2にcmdを表示する
    cmdTextDisplay2->buffer(cmdBuffer2);

    // コマンド実行
    system(cmd.c_str());

    // browser(STDOUT)にコマンドのログを表示する
    browser2 -> load(concatFile.c_str());
    int line_num = browser2->size();
    browser2 -> bottomline(line_num);
}

[C++] 182 FLTK : 動画の一部を複数ぼかす FFmpeg

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, FLTK 1.3.8, NO IDE]

前回作成したコードを導入し、動画の一部を複数ぼかすことができるようにしました。

動画では3ヶ所にモザイクをかけています。

string filterCmdMake(string input,string output,string filters)
{   
    vector<string> crops;
    vector<string> overs;
    string comp;

    vector<string> list_filter = spt2.splits(filters,",");
    int num = list_filter.size();
    
    for (int i=0;i < num;i++){
        string crop = "[0:v]crop=" + list_filter[i] + ",boxblur=4[b" + to_string(i) + "]";
        crops.push_back(crop);
    }

    for (string ele:crops){
        cout << ele << endl;
    }

    for (int i=0;i < num;i++){
        vector<string> values = spt2.splits(list_filter[i],":");
        if (i==0){
            string over = "[0:v][b0]overlay=" + values[2] + ":" + values[3] + "[ovr0]";
            overs.push_back(over);
        } else {
            string over = "[ovr" + to_string(i-1) + "][b" + to_string(i) + "]overlay=" + values[2] + ":" + values[3] + "[ovr" + to_string(i) + "]";
            overs.push_back(over);
        }
    }

    for (string ele:overs){
        cout << ele << endl;
    }

    crops.insert(crops.end(), overs.begin(), overs.end());

    int num2 = crops.size();
    for (int i = 0;i < num2;i++){
        if (i != num2 - 1){
            comp += crops[i] + ";\\" + "\n";
        } else {
            comp += crops[i];
        }
    }

    cout << "comp: " << comp << endl;

    string cmd =  "/opt/homebrew/Cellar/ffmpeg/5.1/bin/ffmpeg -i " + input + " -filter_complex \\\n\"" + comp + "\"\\\n -map \"[ovr" + to_string(num-1) + "]\" " + output;
    cout << "cmd: " << cmd << endl;

    return cmd;
}

[C++] 181 FFmpegコマンド作成 : 動画に複数のぼかしを入れる

[M1 Mac, Big Sur 11.6.8, clang 13.0.0]

動画に複数のぼかしを入れるFFmpegコマンド作成プログラムを書きました。

これで四角形のモザイクを何ヶ所でも入れることができます。

#include <cppstd.h>
#include <Split.h> // 自製文字列分割クラス

class Split spt; 

int main()
{   
    vector<string> crops;
    vector<string> overs;
    string comp;
    string input = "input.mp4";
    string output = "output.mp4";
    string filters = "227:168:411:117,319:177:650:117,416:80:121:657";

    vector<string> list_filter = spt.splits(filters,",");
    int num = list_filter.size();
    
    for (int i=0;i < num;i++){
        string crop = "[0:v]crop=" + list_filter[i] + ",boxblur=4[b" + to_string(i) + "]";
        crops.push_back(crop);
    }

    for (string ele:crops){
        cout << ele << endl;
    }

    for (int i=0;i < num;i++){
        vector<string> values = spt.splits(list_filter[i],":");
        if (i==0){
            string over = "[0:v][b0]overlay=" + values[2] + ":" + values[3] + "[ovr0]";
            overs.push_back(over);
        } else {
            string over = "[ovr" + to_string(i-1) + "][b" + to_string(i) + "]overlay=" + values[2] + ":" + values[3] + "[ovr" + to_string(i) + "]";
            overs.push_back(over);
        }
    }

    for (string ele:overs){
        cout << ele << endl;
    }

    crops.insert(crops.end(), overs.begin(), overs.end());

   int num2 = crops.size();
    for (int i = 0;i < num2;i++){
        if (i != num2 - 1){
            comp += crops[i] + ";\\" + "\n";
        } else {
            comp += crops[i];
        }
    }

    cout << "comp: " << comp << endl;

    string cmd =  "ffmpeg -i " + input + " -filter_complex \\\n\"" + comp + "\"\\\n -map \"[ovr" + to_string(num-1) + "]\" " + output;

    cout << "cmd: " << cmd << endl;
}
--------------------------------------------------
作成されたコマンド
--------------------------------------------------
ffmpeg -i input.mp4 -filter_complex \
"[0:v]crop=227:168:411:117,boxblur=4[b0];\
[0:v]crop=319:177:650:117,boxblur=4[b1];\
[0:v]crop=416:80:121:657,boxblur=4[b2];\
[0:v][b0]overlay=411:117[ovr0];\
[ovr0][b1]overlay=650:117[ovr1];\
[ovr1][b2]overlay=121:657[ovr2]"\
 -map "[ovr2]" output.mp4