[ 前へ | 目次 | 次へ ]
Japanese English
Now Loading...
ダウンロード
PC (※スマートフォンでは動きません) でダウンロードし、ZIPファイルを右クリックメニューから展開して、できたフォルダ内の「 VCSSL.bat(バッチファイル) 」をダブルクリックすると起動します。 Linux等では「 VCSSL.jar 」をコマンド実行してください。
» 詳しい使用方法や、エラーで展開できない際の対応方法などはこちら

C言語のプログラムをGUIで包む(2: 入力値をコマンド引数で渡す編)

VCSSLから、C言語製のプログラムを呼び出し、その出力内容を画面に表示します。

今回は 前回 の発展として、ユーザーからの入力値を、C言語プログラム起動時のコマンド引数として渡すようになっています。

使用方法

ダウンロードと展開(解凍)

まず、PC(スマホは未対応)で上の画面の「 ダウンロード 」ボタンを押してください。 するとZIP形式で圧縮されたファイルがダウンロードされます。

Windows をご使用の方は、ここでまずZIPファイルを右クリックし、「プロパティ」を選んで開かれる画面で、 下の方にあるセキュリティ項目の「許可する」にチェックを入れて「OK」で閉じてください。 これを行わないと、ZIP展開やソフト起動時に、警告メッセージが出て展開完了/起動できない場合があります。

その後、ZIPファイルを右クリックして「すべて展開」や「ここに展開」などで展開(解凍)してください。 展開が成功すると、ZIPファイルと同じ名前のフォルダができ、その中にZIPファイルの中身が入っています。

» 展開がエラーで止まってしまう場合や、ファイル名が文字化けしてしまう場合は…

プログラムの起動

Windows をご使用の場合

上記でZIPファイルを展開したフォルダ内にある、以下のバッチファイルをダブルクリック実行してください:

VCSSL__ダブルクリックでプログラム実行.bat

もしプログラムを書き変えながら使いたい場合は、代わりに「 VCSSL_Editor__プログラム編集はこちら.bat 」を実行してください。

正常に起動できると、初回のみ、Java実行環境を入手するか等を尋ねられるので、適時答えて済ませると、プログラムが起動します。 2回目以降はすぐに起動します。

» うまく起動できずにエラーになってしまう場合は…

Linux 等をご使用の場合

ZIPファイルを展開したフォルダ内へコマンドライン端末で cd して、以下の通り入力して実行してください:

java -jar VCSSL.jar
(プログラムの内容を書き変えながら使いたい場合は、代わりに VCSSL_Editor.jar を実行)

» javaコマンドが使用できない等のエラーが表示される場合は…

起動後

このVCSSLプログラムを実行すると、まず入力ウィンドウが3回立ち上がり、値A,B,Cの入力を求められます:

続いて、以下のようなセキュリティ警告が表示されるので、「はい」を押して続行します。

※ 今回扱う「外部プログラムの実行」処理は、VCSSLのセキュリティの監視範囲の外側で動作するため、何でも行えてしまいます。それを認めますか?という意味です。 信頼できないプログラムでは安易に「はい」は押さないようにしましょう。

なお、毎回このメッセージが出るのがうっとうしい場合は、VCSSLの画面の上から「セキュリティ」>「システムコマンドの実行を許可」にチェックを入れると出なくなります。

すると、C言語製のプログラム program.exe が実行され、先ほど入力した値A,B,Cが、起動時の引数として渡されます。

このサンプルでのC言語プログラムは、起動時の引数 argv の内容を出力するようになっています。 その出力内容は、VCSSLコンソール(黒い画面)上に、以下のように表示されます:

-- C言語プログラムからの出力内容 --
引数[0]の内容: C:\(...略...)\program.exe
引数[1]の内容: aaa
引数[2]の内容: bbbb
引数[3]の内容: ccccc

引数[1]が値A, [2]がB, [3]がCの内容です。

最初に入力した値が、きちんとC言語プログラムに渡されている事を確認できますね。

なお、ここで実行されている「program.exe」は、Windows 用にコンパイルされた実行ファイルであるため、Linux 等の他種OSでは動作しません。 他のOSで実行したい場合は、C言語のソースコード「program.c」をコンパイルし直して、VCSSLからの呼び出し箇所も調整してください(拡張子が .exe ではなく .out 等になるはずです)。

題材解説

この連載について

VCSSLのような簡易的なスクリプト言語のプログラムから、C言語のような「別の言語」で書いたプログラムを呼び出したい、といった場面はよくあります。

今回の記事は、そのテーマでの連載の第2回です。

前回の発展として、起動時の引数でパラメータを渡してみる

初回である 前回 は、

  • 単純な Hello World のC言語プログラムを、VCSSLから呼んで起動して、出力を受け取って表示してみる

という内容を扱いました。

今回はそれを少しだけ発展させて、

  • C言語プログラムに、起動時の引数として、処理に使うパラメータを渡してみる

というサンプルコードになっています。

GUIはまだ単純版、次回でアプリ的な画面を作る

GUIについては、今回はまだ先述の通り、「ポップアップウィンドウを連続表示して、値を入力してもらう」という形態です。

これは、使う際はやや面倒くさいですが、VCSSLでの実装コードが非常に単純で済むという利点があります。実際、今回のコードは、前回のコードに少し追記するだけで済みます。

次回 は、ちょっとしたアプリのような画面を作ってみます。そちらはコードも少し複雑になります。

コード解説

メインのプログラムは、VCSSLで書かれています。VCSSLはC言語系のシンプルな文法を採用しているので、C言語ユーザーの方なら普通に読み書きできると思います。

コード全体

まずVCSSLのコードを見てみましょう。以下がコード内容の全体です:

- GUIWrapperInputArgs.vcssl -

coding UTF-8;

// 必要なライブラリの読み込み
import File;
import Process;

// 実行するC言語プログラムファイルの絶対パスを取得
string programPath = getFilePath("program.exe");

// C言語プログラムを起動する際の、コマンド内容を格納する配列を用意
string commandWords[4];

// 最初の要素は、実行するプログラムのパスを詰める
commandWords[0] = programPath;

// それ以降の要素は、プログラムに渡すパラメータであるため、ユーザーに入力してもらう
commandWords[1] = input("値Aを入力してください:", "aaa");
commandWords[2] = input("値Bを入力してください:", "bbbb");
commandWords[3] = input("値Cを入力してください:", "ccccc");

// プログラムを実行可能な状態に用意する(ここで上記で用意したコマンド内容を渡す)
int processID = newProcess(commandWords);

// 日本語の文字化けを防ぐため、文字コードを指定
// (逆に文字化けしてしまう場合は、"UTF-8" などを指定する)
setProcessInputEncoding(processID, "CP932");
setProcessOutputEncoding(processID, "CP932");
setProcessErrorEncoding(processID, "CP932");

// プログラムを実行し、終了を待機する
startProcess(processID);
waitForProcess(processID);

// プログラムの出力内容を取得し、VCSSLコンソール(黒い画面)に表示
string output = getProcessOutput(processID);
println(output);coding UTF-8;

// 必要なライブラリの読み込み
import File;
import Process;

// 実行するC言語プログラムファイルの絶対パスを取得
string programPath = getFilePath("program.exe");

// C言語プログラムを起動する際の、コマンド内容を格納する配列を用意
string commandWords[4];

// 最初の要素は、実行するプログラムのパスを詰める
commandWords[0] = programPath;

// それ以降の要素は、プログラムに渡すパラメータであるため、ユーザーに入力してもらう
commandWords[1] = input("値Aを入力してください:", "aaa");
commandWords[2] = input("値Bを入力してください:", "bbbb");
commandWords[3] = input("値Cを入力してください:", "ccccc");

// プログラムを実行可能な状態に用意する(ここで上記で用意したコマンド内容を渡す)
int processID = newProcess(commandWords);

// 日本語の文字化けを防ぐため、文字コードを指定
// (逆に文字化けしてしまう場合は、"UTF-8" などを指定する)
setProcessInputEncoding(processID, "CP932");
setProcessOutputEncoding(processID, "CP932");
setProcessErrorEncoding(processID, "CP932");

// プログラムを実行し、終了を待機する
startProcess(processID);
waitForProcess(processID);

// プログラムの出力内容を取得し、VCSSLコンソール(黒い画面)に表示
string output = getProcessOutput(processID);
println(output);
GUIWrapperInputArgs.vcssl

このコードは、内部でC言語製のプログラム「program.exe」(Windows用にコンパイル済み)を呼び出しています。こちらのソースコードは以下の通りです:

- program.c -

#include 

// 以下の引数 argv に、VCSSL側からの入力値が渡される
// ※ argv[0] にはプログラムの名前やパスが格納されているが、それはC言語側の仕様
int main(int argc, char *argv[]) {

    printf("-- C言語プログラムからの出力内容 --\n");

    // 引数 argv の内容を、全て標準出力に表示する
    for (size_t iarg=0; iarg<argc; iarg++) {
        printf("argv[%zu]の内容: %s\n", iarg, argv[iarg]);
    }
}
program.c

上記の通り、起動時に渡された引数 argv の全要素を、標準出力に説明付きで流す内容になっています。出力内容の例は以下の通りです:

-- C言語プログラムからの出力内容 --
argv[0]の内容: C:\(...略...)\program.exe
argv[1]の内容: aaa
argv[2]の内容: bbbb
argv[3]の内容: ccccc

それでは、以降ではVCSSLコードの細部をピックアップして、先頭から順番に見ていきましょう。

ライブラリのインポート

まずは先頭で、このコードが文字コード「UTF-8」で書かれている事を宣言し(誤読対策)、続いて必要なライブラリを読み込んでいます:


coding UTF-8;

// 必要なライブラリの読み込み
import File;
import Process;
import.txt

File は、ファイルパスの取得や変換などを行うライブラリです。今回は実行対象プログラムの絶対パスを取得するのに使用しています。

Process は、外部プログラムの実行や制御を行うためのライブラリです。

実行対象プログラムの絶対パスを求める

次です。ここでは、実行対象の外部プログラムの実行ファイル(今回の場合は program.exe)の絶対パスを求めています:


// 実行するプログラムファイルの絶対パスを取得
string programPath = getFilePath("program.exe");
getpath.txt

これは、プログラムを曖昧な形で指定すると(プログラム名だけなど)、環境によって探す場所の基準や優先度などが異なり、動いたり動かなかったりするトラブルが生じる可能性があるためです。

これは、言語によらず一般論として、あるプログラムから別のプログラムを呼ぶ際に、よく出くわすトラブルです。

なので、初手で絶対パスにしておいた方が安定します。

外部プログラムを実行するコマンドを用意

続いて、外部プログラム(program.exe)を実行するためのコマンド内容を用意します。

ここでコマンド内容というのは、例えばコンパイルしたC言語プログラム(program.exe)を実行する際、従来はコマンドライン端末から

program.exe aaa bbbb ccccc

みたいに入力したりしますよね? あれです。あのコマンド内容を、VCSSLのコード内で用意して、実行をリクエストするわけです。

コマンド内容は、VCSSLのコード内では、文字列型の配列として用意します:


// C言語プログラムを起動する際の、コマンド内容を格納する配列を用意
string commandWords[4];
alloc_commands.txt

そして先頭要素には、実行するプログラム(program.exe)を指定するのですが、先ほどのステップで取得しておいた絶対パスを詰めます(環境による解釈ブレ防ぐため):


// それ以降の要素は、プログラムに渡すパラメータであるため、ユーザーに入力してもらう
commandWords[1] = input("値Aを入力してください:", "aaa");
commandWords[2] = input("値Bを入力してください:", "bbbb");
commandWords[3] = input("値Cを入力してください:", "ccccc");
command0.txt

で、続く [1] 以降には、プログラムに渡すパラメータを詰めます。今回は、ユーザーに尋ねて、値を入力してもらうようにします:


// 最初の要素は、実行するプログラムの絶対パスを詰める
commandWords[0] = programPath;
command123.txt

実行可能な状態に用意

続いて、上記で用意したコマンド内容から、プログラムを実行可能な状態(プロセス)として用意します。これには newProcess 関数を用います。


// プログラムを実行可能な状態に用意する(ここで上記で用意したコマンド内容を渡す)
int processID = newProcess(commandWords);
newprocess.txt

newProcess 関数の引数には、実行対象の外部プログラムのファイルパスを渡すのですが、その際、絶対パスを取得して渡す事が推奨されます。相対パスやファイル名だけだと、実行環境や実行方法によっては失敗する事があるためです。

よってここでは、getFilePath 関数で「program.exe」の絶対パスを取得して、それを newProcess 関数に渡しています。

newProcess 関数は、戻り値として「プロセスID」を返しますが、それを変数 processID に控えています。このプロセスIDは、外部プログラムを実行・制御する際に、引数として指定する必要があります。

文字コード設定

今回のように、外部プログラムの入出力内容が日本語を含んでいる場合には、よく文字化けが問題になります。

そこで、外部プログラムとの入出力に使う文字コードを、実行前に指定します:


// 日本語の文字化けを防ぐため、文字コードを指定
// (逆に文字化けしてしまう場合は、"UTF-8" などを指定する)
// setProcessInputEncoding(processID, "CP932");
// setProcessOutputEncoding(processID, "CP932");
// setProcessErrorEncoding(processID, "CP932");
setencoding.txt

外部プログラムが何かを出力する際、それがどの文字コードを用いるかは、そのプログラムやコンパイラによって異なります。

日本語のメッセージを出力するC言語製のプログラムは、Windows 環境でコンパイルすると、文字コード「CP932(≒Shift_JIS)」を用いる事が結構多い状況です。そのため、上では CP932 を指定しています。

逆にそれによって文字化けしてしまう場合は、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

どちらの方法が扱いやすいかは、出力をどう捌きたいかによります。

今回のコード内容は以上です。

どうだったでしょうか? まだ「GUIで包んだ」と呼べるレベルではないものの、VCSSLからC言語のプログラムを呼び出して、入出力を行う感覚は掴めたでしょうか。

次回 は、いよいよ、ちょっとしたアプリ風のGUI入力画面を作ってみます!

ライセンス

このVCSSL/Vnanoコード( 拡張子が「.vcssl」や「.vnano」のファイル )は実質的な著作権フリー(パブリックドメイン) である CC0 の状態で公開しています。 記事中にC言語/C++/Java言語などでのサンプルコードが掲載されいてる場合は、それらについても同様です。 そのままでのご利用はもちろん、改造や流用などもご自由に行ってください。

※ ただし、このコードの配布フォルダ内には、ダウンロード後すぐに実行できるように、 VCSSLの実行環境も同梱されており、そのライセンス文書は「 License 」フォルダ内に同梱されています (要約すると、商用・非商用問わず自由に使用できますが、使用の結果に対して開発元は一切の責任を負いません、といった具合の内容です)。 配布フォルダ内の各構成物の一覧やライセンスについては「 ReadMe_使用方法_必ずお読みください.txt 」をご参照ください。

※ Vnano の実行環境については、別途スクリプトエンジンのソースコードも一般公開しており、 何らかのソフトウェア内に組み込んでご利用いただく事も可能です。詳細はこちらをご参照ください。


この記事の著者

松井 文宏
[ RINEARN代表, 博士(理学), 応用情報技術者 ]
VCSSLやリニアングラフ3D、その他諸々を開発しています。ガイド類や記事も書いています。

Japanese English
[ 前へ | 目次 | 次へ ]
[an error occurred while processing this directive]
RINEARN からのお知らせ
※ VCSSL は RINEARN が開発しています。

ExevalatorのVer.2.4をリリース—MCPをサポートし、AI用の計算ツールとしても使用可能に
2025-11-15 - 式計算ライブラリExevalatorのVer.2.4をリリースしました。今回から、AIとやり取りするためのプロトコルである「MCP」をサポートし、AI用の計算ツールとしても使用可能になりました!

Exevalatorの最新版Ver.2.3をリリース、新たにPythonで使用可能に
2025-11-04 - 式計算ライブラリExevalatorのVer.2.3をリリースしました。今回から、新たにPython製のプログラムでも使用可能になりました!AI用ツール開発需要などの背景も踏まえて、詳細をお知らせします。

Exevalatorをアップデート、エラーメッセージの日本語化が手軽に
2025-10-31 - 式計算ライブラリExevalatorのVer.2.2.2をリリースしました。今回から、エラーメッセージを手軽に日本語化できるようになりました。数件のバグ修正&微調整も作んでいます。詳細をお知らせします。

関数電卓RINPn(りんぷん)オンライン版の内部構造を解説
2025-10-22 - 先日登場した、関数電卓ソフトRINPn(りんぷん)のオンライン版の内部構造を解説します。オープンソースなので、自由に改造・流用して、自分だけのWeb電卓を作る事も可能!(かもしれない)

関数電卓RINPn(りんぷん)、どこでもすぐ使えるオンライン版が登場!
2025-10-21 - フリー関数電卓ソフトRINPn(りんぷん)に、Web上でどこでもすぐ使える「オンライン版」が新登場しました!PCだけでなく、スマホでも利用可能です。詳細をお知らせします!

VCSSLのサポートAIが登場!ただし実用品質にはChatGPT有料アカウント(Plus)での利用推奨
2025-08-19 - プログラミング言語VCSSLについての質問対応や、コーディング作業を手伝ってくれるAIさんが登場しました!使用までの流れや推奨事項を解説し、実際の回答例や生成コード例などもたくさん紹介します!

各ソフトやVCSSLの英語版ドキュメント整備がほぼ完了
2025-06-30 - RINEARNでは2年前から、AIの補助による英語版ドキュメントの大幅拡充計画を進めてきました。今回、主要ドキュメント&コンテンツの英訳がほぼ完了し、一応の目標水準に達しました。詳細をお知らせします。

VCSSLの最新版をリリース:外部プログラムとの連携機能を少し強化、他
2025-05-25 - VCSSL3.4.52をリリースしました。外部プログラム(C言語製の実行ファイル等)との連携機能を少し強化し、文字化け対策やOS判別などを可能にしました。他にも細かい機能追加があります。詳細をお知らせします。

VCSSLの最新版をリリース、Java24上での非互換な挙動を対処
2025-04-22 - VCSSL3.4.50をリリースしました。Java24環境上でのネットワークドライブ関連のファイルパス解決で、従来環境とは異なる挙動が生じていたのを解消しました。詳細をお知らせします。

リニアングラフやVCSSLの最新版をリリース、目盛りの位置や内容を自由に指定可能に!
2024-11-24 - リニアングラフ3D/2Dを更新し、自由な位置に、自由な表記内容の目盛りを描けるようになりました!併せて、Java言語やVCSSLでの、プログラム制御用APIも拡張しています。詳細をお知らせします。