» 詳しい使用方法や、エラーで展開できない際の対応方法などはこちら
C言語のプログラムをGUIで包む(1: シンプル編)
使用方法
ダウンロードと展開(解凍)
まず、PC(スマホは未対応)で上の画面の「 ダウンロード 」ボタンを押してください。 するとZIP形式で圧縮されたファイルがダウンロードされます。
その後、ZIPファイルを右クリックして「すべて展開」や「ここに展開」などで展開(解凍)してください。 展開が成功すると、ZIPファイルと同じ名前のフォルダができ、その中にZIPファイルの中身が入っています。
» 展開がエラーで止まってしまう場合や、ファイル名が文字化けしてしまう場合は…
プログラムの起動
Windows をご使用の場合
上記でZIPファイルを展開したフォルダ内にある、以下のバッチファイルをダブルクリック実行してください:
もしプログラムを書き変えながら使いたい場合は、代わりに「 VCSSL_Editor__プログラム編集はこちら.bat 」を実行してください。
正常に起動できると、初回のみ、Java実行環境を入手するか等を尋ねられるので、適時答えて済ませると、プログラムが起動します。 2回目以降はすぐに起動します。
Linux 等をご使用の場合
ZIPファイルを展開したフォルダ内へコマンドライン端末で cd して、以下の通り入力して実行してください:
(プログラムの内容を書き変えながら使いたい場合は、代わりに VCSSL_Editor.jar を実行)
» javaコマンドが使用できない等のエラーが表示される場合は…
起動後
このVCSSLプログラムを実行すると、まず以下のようなセキュリティ警告が表示されるので、「はい」を押して続行します。
※ 今回扱う「外部プログラムの実行」処理は、VCSSLのセキュリティの監視範囲の外側で動作するため、何でも行えてしまいます。それを認めますか?という意味です。 信頼できないプログラムでは安易に「はい」は押さないようにしましょう。
なお、毎回このメッセージが出るのがうっとうしい場合は、VCSSLの画面の上から「セキュリティ」>「システムコマンドの実行を許可」にチェックを入れると出なくなります。
続行すると、内部でC言語製のプログラム「program.exe」が呼び出されて実行されます。
そして、その出力内容である「Hello, World!」が、VCSSLの黒い画面(コンソール)に表示されます。
なお、実行しているプログラム「program.exe」は Windows 用にコンパイルされているため、Linux 等の他種OSでは実行できません。 他のOSで実行したい場合は、C言語のコード「program.c」をコンパイルし直して、VCSSLからの呼び出し箇所も調整してください(拡張子が .exe ではなく .out 等になるはずです)。
題材解説
VCSSLのような簡易的なスクリプト言語のプログラムから、C言語のような「別の言語」で書いたプログラムを呼び出したい、といった場面はよくあります。
典型例としては、ちょっとしたGUIツールを作る際、
- ユーザーが操作する画面の部分を、スクリプト言語で書く
- 複雑で重い内部処理などを、C言語などで書く
といった場合が挙げられます。
今回〜今後数回は、実際にそういったテーマでの連載となる予定です。 今回はその第一回として、単純な「Hello, World!」プログラムを呼び出す内容になっています。
コード解説
メインのプログラムは、VCSSLで書かれています。VCSSLはC言語系のシンプルな文法を採用しているので、C言語ユーザーの方なら普通に読み書きできると思います。
コード全体
まずVCSSLのコードを見てみましょう。以下がコード内容の全体です:
- GUIWrapperSimple.vcssl -
coding UTF-8;
// 必要なライブラリの読み込み
import File;
import Process;
// 実行するプログラムファイルの絶対パスを取得
string programPath = getFilePath("program.exe");
// プログラムを実行可能な状態に用意する
int processID = newProcess(programPath);
// もし出力内容が日本語で文字化けする場合は、ここで文字コード指定
// setProcessInputEncoding(processID, "CP932");
// setProcessOutputEncoding(processID, "CP932");
// setProcessErrorEncoding(processID, "CP932");
// プログラムを実行し、終了を待機する
startProcess(processID);
waitForProcess(processID);
// プログラムの出力内容を取得し、VCSSLコンソール(黒い画面)に表示
string output = getProcessOutput(processID);
println(output);
GUIWrapperSimple.vcssl
このコードは、内部でC言語製のプログラム「program.exe」(Windows用にコンパイル済み)を呼び出しています。こちらのソースコードは以下の通りです:
- program.c -
#include
int main() {
printf("Hello, World!\n");
return 0;
}
program.c
何の変哲もない Hello World ですね。このC言語製のプログラムは、直接実行すると、標準出力に
と出力します。
それでは、ここからはVCSSLのコードを、先頭から順を追って解説します。
ライブラリのインポート
まずは先頭で、このコードが文字コード「UTF-8」で書かれている事を宣言し(誤読対策)、続いて必要なライブラリを読み込んでいます:
coding UTF-8;
// 必要なライブラリの読み込み
import File;
import Process;
import.txt
File は、ファイルパスの取得や変換などを行うライブラリです。今回は実行対象プログラムの絶対パスを取得するのに使用しています。
Process は、外部プログラムの実行や制御を行うためのライブラリです。今回行う処理の大部分は、このライブラリの機能の呼び出しです。
実行対象プログラムの用意
次です。ここでは、実行対象の外部プログラムをライブラリの newProcess 関数に知らせて、実行可能な状態に準備してもらっています。
// 実行するプログラムファイルの絶対パスを取得
string programPath = getFilePath("program.exe");
// プログラムを実行可能な状態に用意する
int processID = newProcess(programPath);
new.txt
newProcess 関数の引数には、実行対象の外部プログラムのファイルパスを渡すのですが、その際、絶対パスを取得して渡す事が推奨されます。相対パスやファイル名だけだと、実行環境や実行方法によっては失敗する事があるためです。
よってここでは、getFilePath 関数で「program.exe」の絶対パスを取得して、それを newProcess 関数に渡しています。
newProcess 関数は、戻り値として「プロセスID」を返しますが、それを変数 processID に控えています。このプロセスIDは、外部プログラムを実行・制御する際に、引数として指定する必要があります。
必要に応じて文字コード設定など
次は、今回はコメントアウトしているのですが、外部プログラム実行前の諸設定などです。
// もし入出力内容が日本語で文字化けする場合は、ここで文字コード指定
// setProcessInputEncoding(processID, "CP932");
// setProcessOutputEncoding(processID, "CP932");
// setProcessErrorEncoding(processID, "CP932");
set.txt
この例のように、文字化け対策で文字コードを指定したりする場合がよくあります。
というのも、外部プログラムが何かを出力する際、それがどの文字コードを用いるかは、そのプログラムやコンパイラによって異なるからです。
従って、その出力内容をVCSSL側から読む際に、きちんと合っている文字コードを用いて読まないと、文字化けしてしまいます。
日本語のメッセージを出力するC言語製のプログラムは、Windows 環境でコンパイルすると、文字コード「CP932(≒Shift_JIS)」を用いる事が結構多い状況です。そのため、文字化けする場合は、上記のように、文字コード CP932 を用いる事をVCSSL側に教えてあげます。何も指定しないと、UTF-8 が用いられます。
実行開始と終了待機
続いて、startProcess 関数で外部プログラムを実行し、waitForProcess 関数で終了を待機します。
// プログラムを実行し、終了を待機する
startProcess(processID);
waitForProcess(processID);
start.txt
終了を待機せずに、双方向に入出力を繰り返しながら、処理を進めていく事も可能です。
しかし今回のように「外部プログラムが一方的に内容を出力して終わり」という場合は、実行開始と同時に終了を待機してしまった方が手短です。出力内容は後でまとめて拾えます。
出力内容を取得して、VCSSL側の画面に表示
さて、最後です。外部プログラムが実行中に出力した内容をまとめて取得し、それをVCSSLコンソール(黒い画面)に表示します:
// プログラムの出力内容を取得し、VCSSLコンソール(黒い画面)に表示
string output = getProcessOutput(processID);
println(output);
output.txt
このように、 getProcessOutput 関数で、外部プログラムが今までに出力した内容を取得できます。
他にも、 onProcessOutput イベントハンドラを定義して、行単位でリアルタイムに拾う方法もあります:
void onProcessOutout(int processID, string output) {
print(output);
}
event.txt











