トップ » 技術記事 » 日本語プログラミング言語「なでしこ」プラグインの作り方

日本語プログラミング言語「なでしこ」プラグインの作り方

タグ: なでしこ 日本語プログラミング言語

日本語プログラミング言語「なでしこ」は、日本語でプログラムが作れるユニークなツールです。本稿では、「なでしこ」のプラグインの作り方を紹介します。なでしこには、既に1000を超える組み込み関数がありますが、より高度な処理を行う必要がある場合には、DLL を作成することで、なでしこに新しい機能を追加できます。

なでしことは?

「なでしこ」は、日本語プログラミング言語です。「なでしこで誰でも簡単プログラマー」をスローガンに掲げて、2004年度未踏ユースにて開発が行われました。その後、マイペースに月1回、バージョンアップを続けています。

なでしこの魅力は、なんと言っても「日本語」をベースにしたプログラミングができることです。以下は、ファイルのコピーと圧縮を行うものですが、自然な日本語で記述できることに注目してください。(「マイドキュメント」や「デスクトップ」というのは、Windows の特殊パスを取得するなでしこの命令ですが、このおかげで自然にファイルパスを記述できます。)

「{マイドキュメント}*.doc」から「d:\backup」までファイルコピー。
マイドキュメントを「{デスクトップ}バックアップ.zip」へ圧縮。

基本的に、なでしこでは、動詞が関数、名詞が引数に当たります。助詞によって引数の順番をチェックしていますので、関数の定義を行う時にも助詞を指定する必要もあります。

プラグイン開発に必要な環境

ここでは、なでしこの開発言語として利用している Delphi を使って、なでしこのプラグインを作ってみます。

CodeGear から、Delphiの体験版やフリー版がダウンロードできます。

既に、Delphi が使える方なら簡単にプラグインが作れると思います。また、C や他の言語が使える方なら、少し Delphi(Pascal)に慣れることで開発ができるようになるでしょう。

また、C++言語でなでしこのプラグインを作る際の雛型が以下に用意されています。

プラグインの雛型

プラグインの雛型を、以下に用意しました。この雛型に新しい機能を追加していきます。以下より雛型をダウンロードしてみてください。

なでしこのプラグインは、基本的に、Windows の DLL です。通常の DLL に、なでしこのプラグインとして定められた関数を定義することで、なでしこのプラグインとして認識させることができます。

サンプルのコンパイルとインストール

雛型のプロジェクトをコンパイルするには、上記の雛型を解凍します。そして、DelphiのIDEから、プロジェクトのファイル「plugin_test.dpr」を開きます。そして、実行ボタンをクリック(または、[F9]キーを押す)すると、同じフォルダに「plugin_test.dll」が作成されます。これでなでしこのプラグインの完成しました。

次に、プラグインDLLをなでしこにインストールしてみます。なでしこにインストールするには、なでしこの「plug-ins」フォルダにDLLをコピーします。プラグインをコピーするだけで、なでしこに自動的にプラグインが認識されます。(通常のDLLかプラグインかを判別するのは、定められた関数がDLLに用意されているかどうかで判定しています。)

サンプルのプラグインでは「Sをテスト表示処理」という関数が定義されています。そこで、以下のなでしこのプログラムを実行することで、プラグインのテストを行うことができます。(なでしこのエディタ「nakopad.exe」を起動して、以下のプログラムを記述して、実行ボタンをクリックします。)

「いろは」をテスト表示処理。
一番手軽な開発方法

プラグイン開発を一番手軽に行う方法は、DLLの出力先を、なでしこのplug-insフォルダに設定し、実行時引数を指定するのに、ホストを、なでしこのフォルダにある vnako.exe を指定し、実行時引数になでしこのプログラムを設定する方法です。

http://aoikujira.com/demo/hakkaku/rc/20080609_runtimearg.png

なでしこのプラグインに必要な関数

なでしこのプラグインで必要な関数は次の通りです。Delphi で DLL を作り、関数を外部に公開する場合、次のように「exports」宣言を記述し、外部に公開する関数を一覧で記述します。つまり、以下の6個の関数を定義するとなでしこのプラグインとして認識されます。

// 外部にエクスポートとする関数の一覧
exports
  ImportNakoFunction,
  PluginInfo,
  PluginVersion,
  PluginRequire,
  PluginInit,
  PluginFin;

これらのうち、ほとんどの関数は、雛型に用意されているものをそのまま使えばよく、新たに定義すべきなのは、関数を登録する「ImportNakoFunction」くらいです。

新しい関数を定義する

なでしこに新しい関数を定義するには、次の手順で記述します。

  • (1)新しい関数を定義する
  • (2)関数をなでしこに登録する

それでは、画面に「Hello, World!」を表示するだけの簡単な関数を定義してみます。

新しい関数を定義する

ここでは、サンプル「plugin_test.dpr」を開いて、関数「testFunc」のすぐ下に「sayHello」関数を定義してみます。なでしこに登録する関数は、DWORD 型の引数を1つ取り、PHiValue 型の値を返す形式でなくてはなりません。

function sayHello(h: DWORD): PHiValue; stdcall;
begin
  MessageBox(0, 'test', 'Hello, World!', MB_OK);
  Result := nil;
end;
なでしこのシステムに関数を登録する

次に、上記で定義した関数を、なでしこに登録します。関数を登録するには、「ImportNakoFunction」関数の中で行います。関数を登録するには、「AddFunc()」を使います。

procedure ImportNakoFunction; stdcall;
begin
  // ここに登録したい関数を追加
  AddFunc('挨拶実行','',-1,sayHello,
    '(説明)Hello,Worldと表示する','あいさつじっこう');
end;

この「AddFunc()」の引数には、次のように指定します。

[書式]
AddFunc(
 登録するなでしこの関数の名前,
 関数の引数,
 タグ番号(常に-1),
 コールバック関数,
 関数の説明,
 よみがな
);

なでしこがユニークなのは、関数の登録時に、関数の名前や、登録する関数、関数の説明や、ふりがなまでを指定するという点です。これにより、マニュアルを自動生成するのに役立ちます。

引数と戻り値を指定する

上記で定義したのは、引数も戻り値も取らない関数でした。そこで、次に引数と戻り値を持つ関数を定義してみます。例として、足し算を行うだけの関数を定義してみます。

足し算を行う関数の定義

まずは、なでしこに登録するコールバック関数を定義します。

// 足し算を行う関数
function tasizan(h: DWORD): PHiValue; stdcall;
var
  a, b, c: Integer;
begin
  // (1) 引数の取得
  a := getArgInt(h, 0); // 0番目の引数を得る
  b := getArgInt(h, 1); // 1番目の引数を得る

  // (2) 処理
  c := a + b;

  // (3) 戻り値の設定
  Result := hi_newInt( c ); // 整数型の戻り値を指定する
end;

コールバック関数で整数型の引数を得るには、「getArgInt()」関数を使います。コールバック関数は、常に一定の形をしているので、自由に引数を取ることができません。そのため、関数の中で、引数を取得する命令を呼び出すことで、引数を得ることができます。

ちなみに、文字列の引数を得るには、「getArgStr()」を、実数型の引数を得るには、「getArgFloat()」、真偽(BOOL)型を得るには、「getArgBool()」が用意されています。

これらは、なでしこの変数を表す PHiValue 型をDelphiの型に合わせるもので、ネイティブな値を得たい場合は、「nako_getFuncArg()」を使います。(ネイティブ型を得ることにより、引数自身の書き換えを行うこともできます。)

ちなみに、「getArgXXX()」の関数の使い方は、1つ目の引数に引数ハンドル(コールバック関数唯一の引数)を、2つ目の引数に、何番目の引数を得るのかを指定します(0起点です)。

それから、整数の戻り値を指定する場合は「Result := hi_newInt( 整数 );」のように書きます。「Result」というのは、Pascal で関数の値を指定するのに使われるシステム変数です。「hi_newInt()」関数で、なでしこの整数を作成し値を戻します。文字列を返す場合には「hi_newStr()」関数が用意されています。

足し算を行う関数をなでしこに登録する

次に、先ほどと同じようにして、「ImportNakoFunction」で関数を登録してみましょう。なでしこで、引数を定義するには「AとBを」のように指定します。なでしこの変数は、動的に型が変化するものなので、関数定義に変数の型、戻り値の型を指定する必要はありません。

procedure ImportNakoFunction; stdcall;
begin
  AddFunc('テスト足し算','AとBを',-1,tasizan,'足し算','てすとたしざん');
end;

まとめ

以上、簡単になでしこのプラグインを作る方法を紹介しました。なでしこだけでは実現できないことも、プラグインを作ることで実現できることがあります。例えば、なでしこでは、簡単な Windows API を呼ぶことができますが、複雑な構造体を持つWindows APIを呼ぶのは面倒です。そこで、DLLを作ることで、こうした API を手軽に呼ぶことができるでしょう。ぜひ、本稿を参考にして、なでしこのプラグインを作ってみてください。


執筆者紹介

クジラ飛行机

クジラ飛行机

くじらはんど(http://kujirahand/)にて、日本語プログラミング言語「なでしこ」(IPA未踏ユース採択)、テキスト音楽「サクラ」(OSPオンラインソフト大賞入賞)など多くのオンラインソフトを開発。著書に「Flexプロフェッショナルガイド」「なでしこ公式バイブル」、「一週間でマスターするActionScript3.0」など。

TrackBack URL :