REALbasic Plugin の作成調査

SPECIAL

REALbasic のプラグインを作ろうと CodeWarrior を買ったはいいけど、わからんわからん。

というわけで、奮闘開始…。


REALbasic と Plugin

REALbasic は、ASCII が販売している Apple Macintosh 用のプログラム言語です。

Windows でいうところの、Visual Basic や Delphi といった感じのいわゆる RAD ツールなので、ビジネス系のアプリケーションを効率よく作成できるのが魅力です。

また、そうとううまくやらないといけない感じですけど、同一のプログラムソースを使って、Windows 版のバイナリファイルを書き出すことも出来ます。なので、うまくやれば、一瞬にして Windows / Classic Mac / Carbon (MacOS X) のプログラムが出来上がってしまうわけですが、現時点の Version 3.5.2J では、そうやすやすと両方で動くプログラムは作れませんでした。

 

この REALbasic、そのままの状態でもけっこういろいろな機能が備わっていて、普通のことをするならば BASIC 言語だけで何とかなってしまうのですが、複雑なことをやろうとすると不満も出てきます。処理速度の遅さが目立ったり、REALbasic 自身では実現できない機能が必要であったり…。

そんなときに、REALbasic の不足を補填する役割を担うのが、プラグインです。C++ を使えないといけないので一気に敷居が高くなりますけど、拡張できるというのはいいことですね。

また、プラグインは、plugins フォルダ内で一括管理されるので、REALbasic のモジュールとかみたいに、どこのプロジェクトに入っているモジュールが最新かわからなくなるといった心配がなさそうで、それもまた魅力的です。

 

とりあえず開発環境をそろえてみる

そんなプラグインを作りたい=、ということで、いろいろと調査が始まりました。

プラグインを作成するためのライブラリが、REALbasic のサイトのダウンロードページ から入手できるようになっています。今回はここで入手できる REALbasic Plug-ins SDK (3.5a1) をダウンロードしてみました。

 

で、この SDK のプラットホームとなるのが、Metrowerks 社の CodeWarrior という開発ツール。

このツールは Windows 版と Macintosh 版の両方が出ているのですが、どちらにせよお値段がかなりのものです。もともと Mac 用の C++ 開発ツールが欲しかったので、いいきっかけにはなったのですが…。

買うときに悩んだのが、Windows 版と Macintosh 版のどちらにするか。結局、+2万円で Windows / Macintosh 版の両方がついた、CodeWarrior 7 を購入することになりました。

単純に Macintosh 版の CodeWarrior 7 が見つからなくて、両方入ったのになったのですが…。

買ってみてわかったのが、Windows 版では PowerPC 版のバイナリを書き出せないようです。マニュアルを見ると、なんだか英語版のみというような表記が…。もしかしてダメ? とか思ったら、CodeWarrior のインストール後に、追加セットアップを行ってみると、PowerPC 用のがありました。

あともうひとつ。なんだか Mac 版のほうも、68k のバイナリは書き出せないような感じがします。僕にとっては痛くなかったのですが、買うまで知りませんでした。となると、68k 版のプラグインは作れないということですね…。

 

プラグインのインストール

環境が整ったので、さっそく REALbasic Plug-ins SDK を、CodeWarrior 7 / Mac に導入してみました。

プラグインを展開したフォルダの中にある、CodeWarrior Plug-Ins というフォルダの中に、"RB DLL Plugin Panel" と、"RB DLL Plugin PostLinker" という2つのファイルが入っています。

これを CodeWarrior のプラグインフォルダに入れろと書いてありますが、:Metrowerks CodeWarrior 7.0:Metrowerks CodeWarrior:CodeWarrior Plugins フォルダの中を見ても、なにやらたくさんフォルダがありました。

おそらくこの中の適切なフォルダにコピーするのだろうと思い、ファイル名やアイコンを頼りに分類してみました結果、"RB DLL Plugin Panel" は :Preference Panels フォルダへ、そして "RB DLL Plugin PostLinker" は :Linkers フォルダへコピーすることにしました。 

 

さて、ちゃんと導入できたかのチェックなのですが…、CodeWarrior なんて使ったことがないため、どうやったらちゃんと導入できているのかさっぱりでした。

別にプロジェクトの中に新しく REALbasic プラグイン用の何かが出てくるわけでもないし、適当なプロジェクトでビルドの調整をしようとしても、別にリンカとかで REALbasic っぽいのが表示されるわけでもないし…。

ということでいろいろと試していたのですが、どうやらこれでプラグインの導入はちゃんと出来ているようです。

リンカは Win 用のプラグインを作るときに必要みたいで、ターゲットを Win32 x86 にした場合、ポストリンカの項目で選択可能になるみたいでした。

 

サンプルプラグインをコンパイルしてみる…

さて、プラグインがちゃんと導入されているのならば、REALbasic プラグインのアーカイブの中にあった、サンプルのプラグインをコンパイルすることが出来るはず。

ということで、:Examples フォルダの中にあった PluginTest を使って実験してみました。

 

この PluginTest がどのバージョンの CodeWarrior で作成されたかはわかりませんけど、なにやらプロジェクトを変換しないといけないようです。

PluginTest.mcp をダブルクリックするとプロジェクトを変換するかを尋ねられましたので、とりあえず 「変換」 を選択しました。

そして開いてみると、MSL_Runtime_PPC.Lib が見つからないとのこと…。実際に登録されているターゲットをビルドしようとしてみても、いろんなところでファイルが見つからないというエラーが発生してしまってぜんぜんでした。

 

MacOS X (Carbon) 用

使っている OS は MacOS X だったので、とりあえず Carbon 版はできるようにならないかなぁ…、ということでパスのあら捜しをしてみました。

Carbon.h が見つからないといわれたので、これが保存されているフォルダパスを追加したり、パスが見つからないといわれるエントリを削除したり…。

結局、"MacOS X:System:Library:CFMSupport:"、"MacOS X:Applications:Metroerks CodeWarrior 7.0:Metrowerks CodeWarrior:MacOS Support:Universal:Interfaces:CIncludes:" の2つをシステムパスへ、そして REALbasic Plugin のアーカイブに入っていた Includes フォルダと Glue Code フォルダへのパスをユーザパスへ追加したら、Carbon 版のプラグインが生成できるようになったみたいです。

実際に、REALbasic の Plugins フォルダへ出来上がったプラグインをコピーしてみると、ちゃんと認識されて、ちゃんと使うことが出来ました。

 

ClassicMac / PowerPC 用

Classic 環境版の方はこれだけではさっぱりでした。

Carbon の時と同じようにヘッダーファイルが見つからないというエラーがいくつか出てきたのですが、A4Stuff.h と SetupA4.h というヘッダがハードディスク上にはありませんでした。

いろいろとインターネットで調べてみると、なにやらこのあたりのコードは 68k バイナリを生成するときに使用するもので、PPC ならばいらないのだとか…。

PluginMain.cpp の中の、#include<A4Stuff.h> と #include<SetupA4.h> の2つを削除して、さらにそのヘッダファイルの中に記述されている EnterCodeResource() と ExitCodeResource の行を削除…。

こうしてみたら、無事、PPC 版のプラグインも作ることが出来ました。PPC 版の REALbasic で確認してみると、ちゃんと認識されて動きました。

 

これら A4Stuff.h と SetupA4.h ですが、http://www.triplesoft.com/fragment/sourcecode.html というページをみると、コードが書いてありました。このコードを使って、これらのファイルを自分で作ると、コードを削ることなく PPC のプラグインを生成できるようです。

一応、SetupA4.hA4Stuff.h にここのコードをまとめたものを作って見ました。が、これらが本来の機能を振舞ってくれるかは確認していません。

単純に、このファイルを使っても、動くプラグインがビルドできたというだけです。なのでこれらのファイルを使用する場合は各自の責任でお願いします。

これでちゃんと動く保障はありませんけど、まぁ、提供されたプラグインのソースコードを改変したくない人は試してみる価値があるかと思います。

ClassicMac / 68k 用のプラグイン

これは CodeWarrior 7 ではだめなのでしょうか…。

そもそもリンカの選択の部分で MacOS 68K Linker が選択できないため、なすすべなく断念です。

Windows / x86 用のプラグイン

とにかく致命的と思われるのが、RB DLL Plugin PostLinker が見つからないというエラー。

いろいろと試していくと、どうやら CodeWarrior 7 が Carbon で動いていると、RB DLL Plugin PostLinker をうまく見つけることが出来ないようです。CodeWarrior 7 が Classic 環境で動いていれば、ちゃんと PostLinker を見つけることが出来るようです。

しかしながら、もうひとつ問題があって、コンパイル中に "void* から char** への不当な暗黙の型変換です。" というエラーが、AEDataModel.h という共有ヘッダで発生してしまいました。

さすがにこのファイルにいろいろと手を加えるわけにも行かず…、あんまり Windows 版のプラグインに興味がなかったので、とりあえずここまで、ということで断念です。

 

自力でプラグイン用のプロジェクトを組み上げる

さて、上記のように PluginTest がビルドできるようになったので、これを改造すれば独自のプラグインを作成できることにはなったのですが、いろいろといじったりしないといけないため、ちょっと気分がスッキリしませんでした。

なので、これまた試行錯誤でなんですが、CodeWarrior 7 に用意されているプロジェクトをつかって、REALbasic プラグインが書き出せるようにしてみることにしました。

手を加えていくプロジェクトは、"Mac OS C++ ステーショナリ" の中にあるコンソールプログラム用のプロジェクトにします。なんだか一番シンプルそうだったので…。

 

プロジェクトの準備

CodeWarrior 7 を起動したら、新規で "Mac OS C++ ステーショナリ" を選択します。プロジェクト名は "REALbasic Plugin MacOS.mcp" としておきました。もちろん、プロジェクト名は何でもいいです。

そして、Multi-Target -> Standard Console -> C++ Console Multi-Target を選択します。

 

そしたらば既存のターゲットの、Classic C++ Console Final と Carbon C++ Console Final の2つだけを残して他を削除します。

別に削除しなくてもいいのですが、今回は上記のターゲット2つを修正しようと思っているので、それ以外のターゲットは削除しておくことにしました。

 

さて、そうしたら、Source グループの中にある HelloWorld.cp ファイルは使わないので削除します。

それと Libraries [Classic / Carbon] グループの中の MathLib, TextCommon, UnicodeConverter, UTCUtils を消去します。また、Libraries [Mach-O] グループも不要なので丸ごと削除します。

 

そしてプラグイン作成に必要なファイルを、プロジェクトに追加します。

REALbasic プラグイン SDK の中に入っていた、Glue Code と Includes フォルダの両方を、プロジェクトフォルダの中へコピーします。

そうしたら、Glue Code フォルダの中にある PluginMain.cpp をプロジェクトへ追加します。このとき、Classic C++ Console Final と Carbon C++ Console Final の両方に、このファイルをリンクさせておきます。

 

これで大まかな部分は終わりです。続いて、個々のターゲットの調整を行います。

 

Carbon 用のプラグイン

ターゲットの Carbon C++ Console Final の設定ダイアログを開きます。

 

<ターゲット> ターゲット設定

これはやらなくてもぜんぜん問題ないですけど、とりあえず 【ターゲット名】 を REALbasic Plugin / Carbon とでも変更しておきます。

ほかの情報はそのままです。プリリンカとポストリンカは ”なし” です。

<ターゲット> アクセスパス

ユーザパスとして、"{Project}:Glue Code" と "{Project}:Includes" の2つを登録します。

登録の仕方は、ユーザパス用のリストボックスをクリックしてから、ダイアログの下のほうにある 【追加】 ボタンをクリックします。

そしてこのプロジェクト内の Glue Code フォルダ、または Includes フォルダを選択して、下のほうにある 【相対】 という名のプルダウンメニューから ”プロジェクト” を選択して、右下の 【選択】 を押します。

>> 詳細画像

<ターゲット> PPC ターゲット

【プロジェクトの種類】 を ”コードリソース” に変更します。【ファイル名】 はビルド後に出来上がるファイル名です。とりあえず、REALbasicPlugin.Carbon としておきました。

そして、【クリエータ】、【タイプ】、【リソースタイプ】、【リソース ID】 を、次のように設定します。

クリエータ RBv2
タイプ RBPl
リソースタイプ PLCN
リソース ID 128

リソース ID は各リソースタイプごとに 128 から連番でつける必要があるそうです。また、PLCN というリソースタイプは、ClassicMac 用 (PowerPC) のプラグインであることを意味します。

補足ですが、タイプの最後の文字は、小文字の L です。

それと 【ヘッダータイプ】 は ”なし” に設定します。試行錯誤の結果なのでなんともいえませんけど、なしにしないと REALbasic がうまく動かなくなるようです。

>> 詳細画像

<言語設定> C/C++ 言語

ここで重要となるのは2箇所です。

ひとつは 【ANSI に厳格にしたがう】 の部分。ここのチェックをはずさないと、コンパイル時にエラーが発生します。

もうひとつが 【プリフィックス ファイル】。この部分には "CarbonHeaders.h" と打ち込みます。

<リンカ> PPC リンカ

下のほうにある1箇所、【メイン】 の部分を "__start" から "main" に変更します。

 

PPC 用のプラグイン

ターゲットの Classic C++ Console Final の設定ダイアログを開きます。

ほとんどが上記の Carbon の時と共通ですけど、一部違うところがありますので、そのあたりに重点を置いて書いてみます。説明が足りない部分は上記の Carbon 編を参考にしてください。

 

<ターゲット> ターゲット設定

これもやらなくてもぜんぜん問題ないですけど、とりあえず 【ターゲット名】 を REALbasic Plugin / Classic とでも変更しておきます。ほかの情報はそのままです。

<ターゲット> アクセスパス

ユーザパスとして、"{Project}:Glue Code" と "{Project}:Includes" の2つを登録します。

あと上のほうで A4Stuff.h と SetupA4.h のお話をしましたが、もしこれらのヘッダファイルを用意してあるのならば、これらのファイルが保存されているフォルダを、システムパスの方へ追加します。

<ターゲット> PPC ターゲット

【プロジェクトの種類】 を ”コードリソース” に変更します。【ファイル名】 はビルド後に出来上がるファイル名です。とりあえず、REALbasicPlugin.Classic としておきました。

そして、【クリエータ】、【タイプ】、【リソースタイプ】、【リソース ID】 を、次のように設定します。

クリエータ RBv2
タイプ RBPl
リソースタイプ PLPC
リソース ID 128

Carbon 版とは違う場所が2箇所あります。

ひとつが 【リソースタイプ】。これは ClassicMac 版をあらわす PLPC を指定する必要があります。そしてもうひとつが 【ヘッダータイプ】 です。Classic の場合、ここは "Native" を選択します。

<言語設定> C/C++ 言語

ここで重要となるのは2箇所です。

ひとつは 【ANSI に厳格にしたがう】 の部分。ここのチェックをはずさないと、コンパイル時にエラーが発生します。

もうひとつが 【プリフィックス ファイル】。この部分には "MacHeaders.h" と打ち込みます。Carbon のときとは、打ち込む文字列が異なるので気をつけましょう。

<リンカ> PPC リンカ

下のほうにある1箇所、【メイン】 の部分を "__start" から "main" に変更します。

 

REALbasic に組み込める形へ

さて、ここまできたらとりあえずビルドしてみることにしましょう。ターゲットで "REALbasic Plugin / Carbon" を選択して、ビルドボタンを押します。

警告として ”変数/引数 "unused" は関数内で使用されていません。” というメッセージが表示されますが、これは無視して大丈夫です。このほかに PluginEntry (code) でリンクエラーが出ますが、これもすぐになくなります。

とりあえず、上記2つのメッセージがでるだけならば、ここまではちゃんと設定できたことになります。

 

本来はこれからプラグインのコードを書き始めるわけですが、今回は話を簡単にするため、Examples の中の PluginTest フォルダに入っている、pluginTest.cpp を拝借することにします。

これはプラグイン用のプログラムを書く手間を省くためです。というか、まだ僕自身がプラグインのコードを書けないという理由もありますが…。

 

pluginTest.cpp をコピーしたら、ファイルをプロジェクトに追加します。追加の際には、REALbasic Plugin / Classic と REALbasic Plugin / Carbin の両方に追加してやります。

さて、これで準備完了です。両方のターゲットをビルドしてみましょう。今度は警告はあってもエラーはなくなっていると思います。

 

続いて、出来上がった REALbasicPlugin.Carbon と REALbasicPlugin.Classic のチェックを行ってみます。

REALbasic の Plugins フォルダへ、まずは REALbasicPlugin.Carbon をコピーして、Carbon 版の REALbasic を起動してみます。すると、ツールウィンドウの下のほうに、testPlugin コントロールが表示されています。適当に貼ってみても、ちゃんと動くことが確認できました。

今度は、REALbasic.Classic の方を REALbasic の Plugins フォルダへいれて、Classic 版の REALbasic を動かしてみます。今度はちゃんと Classic 環境で動くことが確認できました。

 

今のところ、Classic 用のプラグインは Classic 環境の REALbasic でしか、逆に Carbon 用のプラグインは Carbon 環境の REALbasic でしか認識されません。

なので、このままだと両方でプラグインを動かすためには、Classic 版と Carbon 版の両方のファイルを Plugins フォルダへ入れておかなくてはいけないことになってしまいます。

なので、これらを混ぜてひとつにしてしまいましょう、というのが次のお話。

 

Classic/Carbon 両対応のプラグインを作る

Classic 版と Carbon 版のそれぞれが、べつべつのファイルとして存在しているのは何かと不便なので、これらをひとつにまとめるための ”ターゲット” を、上記で作った REALbasicPlugin MacOS プロジェクトに追加してみましょう。

 

ターゲットの作成

まず、ターゲットを新規に作成します。

このとき、【新規ターゲットの内容】 は ”何も追加しない” を指定します。【新規ターゲット名】 はなんでもいいのですが、とりあえず "REALbasic Plugin Merge-Out" とします。

ターゲットが出来上がったら、続いてターゲットの設定を調節します。

 

<ターゲット> ターゲット設定

【リンカ】 として、"MacOS Merge" を選択します。

<ターゲット> ファイルマッピング

マッピング情報に次のように入力したら、【追加】 ボタンを押します。

ファイルタイプ RBPl
拡張子  
フラグ リソース
コンパイラ なし
使用言語 なし

こうすることによってプロジェクトに、ファイルタイプ RBPl を持ったファイル、つまり REALbasic のプラグインが追加できるようになります。

<リンカ> MacOS マージ

【プロジェクトタイプ】 として、”リソースファイル” を選択します。

【ファイル名】 は書き出されるファイルの名前なので何でもいいのですが、今回は "REALbasicPlugin.Mac" としました。

そして、【クリエータ】 には "RBv2" を、タイプには "RBPl" を設定します。

 

プラグインのリンク

ターゲットの設定が終わったら、ファイルのところに新しいグループを作成します。

名前は何でもいいですが、"Maked Plugins" とでもしましょう。グループは作成しなくてもかまわないのですが、見た目の都合上、追加しておくとなんだかすっきりします。

 

そしてそこへ先ほどビルドした REALbasicPlugin.Carbon と REALbasicPlugin.Classic を放り込みます。このとき、追加するターゲットとして、”REALbasic Plugin Merge-Out" だけを選択するようにします。

 これで準備はすべて完了です。

あとは、ビルドボタンを押せば、Classic 版と Carbon 版の両方が詰まったプラグインファイルが出来上がります。

 

では動作確認をして見ましょう。

REALbasic の Plugins フォルダへ今作った REALbasicPlugin.Mac をコピーします。そして Carbon 版の REALbasic を動かしてみると、ちゃんとプラグインが認識されていることが確認できます。続いて、Classic 版の REALbasic で試してみると、こっちでもちゃんとプラグインが認識されていました。

これで、Classic/Carbon 両対応のプラグインが、ひとつのファイルで管理できるようになりました。

 

調査終了

これにて調査終了です。

まだ REALbasic のプラグインの実際のプログラミングについてはまったく知らないので、この調査も不十分なところがあるかもしれませんけど、なんだか Mac 版のプラグインならばしっかりと作っていけそうな感じですね。

暇が出来たらガシガシと作って行きたいなぁ…。そうしたら、きっとこのページも手直しされていくことになるのでしょう…。