Development」カテゴリーアーカイブ

UBオブジェクト開発講座(4) オブジェクトのビルド構成

UBオブジェクト開発講座の4回目は、オブジェクトのビルド構成についてです。同じオブジェクトでも、コンパイルやリンクの仕方によって異なるコードを生成することができます。このような設定をXocdeではビルド構成と呼んでおり、UBオブジェクトのビルド構成については、「Details About Xcode Projects for Max Externals」に説明されています。以下は、この文章の要点だけを抜き出したものです。

C74がUBオブジェクト用に用意しているビルド構成には、DevelopmentとDeploymentの2種類があります。これらの特徴的な設定は、以下の通りです。

buildsettings.gif

要するに(というか文字通りなのですが)、開発中はDevelopmentを選びます。この設定はコンパイルが速く、デバッガを利用することができ、クラッシュ・ログにも記録が残るからです。

そして、開発が完了して一般に公開する時に、Deploymentに設定してビルドを行い、Deploymentフォルダに作成されたオブジェクトを配布します。このオブジェクトはUniversal Binaryなので、PowerPC MacでもIntel Macでも動作することになります。

ただし、これらとは別にDefalutという構成も用意されていて、これがデフォルトの設定になっています。Defaultは、C74の文章では説明されていませんが、実際にはDevelopmentと同じ設定内容になっているようです。想像するに、Defaultはユーザの好みに合わせて設定を変えるために用意されていて、DevelopmentとDeploymentは設定を変えずにそのまま使ってね、ってことじゃないかな。

なお、C74の文章では、ビルド構成の主要な項目についても説明されていますが、ここでは省略します。特殊なオブジェクトの開発や我がままな開発スタイルを貫きたい場合を除けば、一般的にはDevelopmentまたはDeploymentのいずれかを選ぶだけで事足りますからね。というわけで、今回はとっても短い説明になりました。めでたしめでたし。

UBオブジェクト開発講座 休題

UBオブジェクト開発講座は、3回分が終わったところで一休みです。後から見直すと、他の記事との景観が合いませんね〜特に第3回は記号多過ぎ分量多過ぎでございました(苦笑)。また、投稿逆順に並ぶブログ形式と連載形式も合いませんね。個人サイトに書くほうが良いかもしれませんが、情報が分散するのもイヤなので、DSPマガジン亡き現在、このサイトに集約しておこうと思うわけです。

内容としても、多くの人にとっては興味がないというかチンプンカンプンだとは思うのですが、とりあえず書いておけば、いつか誰かの役に立つかもといった程度なので、軽く流しておいてください。また、この後の展開も、例えばデバッグとかOS APIとかいろいろと考えられるわけですが、さてさて、どうなんでしょうか?

UBオブジェクト開発講座(3) ソース・コードの概要

第3回UBオブジェクト開発講座は、サンプルとして提供されているmaximumオブジェクトを題材に、そのソース・コードの概要を説明します。これは、以前に公開した「Maxオブジェクト開発技法」から主要部を抜き出し、MaxMSP UB SDK用にアップデートしたものです。

日本語コメントを付けたソース・コードは、こちらからダウンロードしてください。
maximum-jcommented.zip

以下は要点のみをザザっと俯瞰しています。

■処理の概要

Maxオブジェクトのソース・コードは、大きく3つの部分から構成されています。

(1) メイン関数 main()【必須】

Max起動時やパッチを開いた時など、オブジェクトが読み込まれた時に呼び出され、クラスとして必要な初期化などの設定を行います。具体的には、以下の2つの処理が必須ですが、必要に応じてその他の処理を行っても構いません。
・クラスの設定を行う。setup()【必須】
・メッセージ処理関数を登録する。【ほぼ必須】

(2) メッセージ処理関数 maximum_bang()など【ほぼ必須】

オブジェクトにメッセージが送られた時に対応する関数が呼び出されます。メッセージ処理関数の引数は、その登録によって異なります。

(3) オブジェクト生成関数 maximum_new()【必須】

オブジェクト生成時に呼び出され、インスタンスとして必要な初期化などの設定を行います。具体的には、以下の3つの処理が必須ですが、必要に応じてその他の処理を行っても構いません。
・オブジェクトを生成する。newobject()【必須】
・アーギュメントの処理、インレット、アウトレットの作成などを行う。
(右から左への順序で。第1インレットはnewobject()が自動的に作成する。)
・生成したオブジェクトへのポインタを関数の戻り値として返す。【必須】

なお、maximumでは必要がありませんが、オブジェクト生成関数において、メモリの確保やデバイスのオープンなどを行った場合は、オブジェクト消滅関数を登録(setup()の3番目の引数で指定)し、その関数でメモリの解放やデバイスのクローズなどの処理を行うようにします。

■メッセージ処理関数の登録

メッセージ処理関数を登録するには、以下の関数を用います。これらはext_proto.hに定義されています。

void addbang(method f); // bangメッセージ処理関数の登録
void addint(method f); // 整数メッセージ処理関数の登録
void addfloat(method f); // 実数メッセージ処理関数の登録
void addinx(method f, short n); // 第nインレットでの整数メッセージ処理関数の登録
void addftx(method f, short n); // 第nインレットでの実数メッセージ処理関数の登録

fはメッセージ処理関数へのポインタ、nはインレット番号(0始まり、第2インレットは1)

void addmess(method f, char *s, short type, ...); // 任意のメッセージ処理関数の登録

sはメッセージ文字列、typeはアーギュメントのデータ・タイプで、アーギュメントの数に応じて並べ、最後は0で終えます。詳しくは、次の「メッセージ処理関数への引数」最後の部分を参照してください。

オブジェクトがメッセージを受け取る時に、登録されたメッセージ処理関数に従って、メッセージやアーギュメントがチェックされ、一致しなければ自動的にエラーとなります。

■メッセージ処理関数への引数

メッセージ処理関数の種類によって、以下のように受け取る引数は異なります。

bangメッセージ処理関数は、次の引数を受け取ります。

void maximum_bang(t_maximum *x)

xはオブジェクト構造体へのポインタを表します。
bangメッセージはアーギュメントを持ちませんから、これ以外の引数はありません。

整数メッセージ処理関数は、次の引数を受け取ります。

void maximum_int(t_maximum *x, long n)

xはオブジェクト構造体へのポインタ、nは送られた整数を表します。

リスト・メッセージ処理関数は、次の引数を受け取ります。

void maximum_list(t_maximum *x, t_symbol *s, short ac, t_atom *av)

sはメッセージのシンボル(list)、acはリストの要素数、avはリストの最初の要素へのポインタを表します。

「jack n m」というメッセージの処理関数は以下のようになります。ここでは、nとmは整数で、nは省略不可、mは省略可能とします。

void maximum_jack(t_maximum *x, long n, long m)

xはオブジェクト構造体へのポインタ、nとmは送られた整数を表します。

なお、このメッセージ処理関数を登録するには、以下のように記述します。

addmess((method)maximum_jack, "jack", A_LONG, A_DEFLONG, 0);

■データ・タイプ

Maxが用いるデータの種類を表すデータ・タイプは、ext_mess.hに以下のように定義されています。

#define A_NOTHING 0 // 無(データはないことを示す)
#define A_LONG 1 // 整数
#define A_FLOAT 2 // 実数
#define A_SYM 3 // シンボル
#define A_OBJ 4 // オブジェクト、アーギュメントの配列
#define A_DEFLONG 5 // デフォルト値が0である整数
#define A_DEFFLOAT 6 // デフォルト値が0.0である実数
#define A_DEFSYM 7 // デフォルト値が""であるシンボル
#define A_GIMME 8 // アーギュメントの配列、t_atomの配列であることをチェック
#define A_CANT 9 // タイプチェック不能/不要であるアーギュメント
#define A_SEMI 10 // ;(セミコロン)
#define A_COMMA 11 // .(コンマ)
#define A_DOLLAR 12 // $(ドルマーク)
#define A_DOLLSYM 13 // $(ドルマークのシンボル)
#define A_GIMMEBACK 14 // アーギュメントの配列、関数でチェックして戻す

■データ構造

Maxのデータ(整数、実数、シンボル)はすべてt_atom(Atom)構造体で表され、データの種類を表すデータ・タイプと実際のデータ値の2つの要素から構成されています。データ値は共用体として、異なるタイプのデータが納められるようになっています。

union word // データ値の共用体
{
long w_long;
float w_float;
struct symbol *w_sym;
struct object *w_obj;
};

typedef struct atom // データの構造体
{
short a_type; // データ・タイプ
union word a_w; // データ値
} t_atom, Atom;

例:t_atom *data の場合、
データの値を参照するには、データ・タイプを確認した上で、データの値を取り出します。例えば、データが整数である場合は、以下のようになります。データ・タイプが明確であれば、データ・タイプの確認は省略しても構いません。

if (data->a_type == A_LONG)
value = data->a_w.w_long;

データに値を代入する場合は、データ・タイプを設定した上で、実際の値を代入します。例えば、整数を代入するには以下のようになります。

data->a_type = A_LONG;
data->a_w.w_long = 100;

UBオブジェクト開発講座(2) オリジナル・オブジェクトの作成

UBオブジェクト開発講座の第2回は、オリジナルのオブジェクトを作成する方法で、要は既存のサンプル・プロジェクトの複製を作り、必要な箇所を変えれば、ハイ出来上がり、というわけです。ここでの説明は「Copying An Example Project」の抄訳を元に、多少の補足を加えています。

Step 1: Finderでmaximumフォルダの複製を作り、フォルダ名を変える。ここではgoofyという名前とする。goofyフォルダは、c74supportフォルダと同じ階層のフォルダ(例えば、example-externsフォルダ)に納めるのが良い。

Step 2: goofyフォルダを開き、Xcodeのプロジェクト・ファイル名を変える。ここでは、goofy.xcodeprojという名前とする。

Step 3: 既に作成しているC言語のソース・ファイルがあれば、それをプロジェクト・フォルダにコピーする。なければ、maximum.cを自分が用いる名前に変える。ここでは、goofy.cという名前とする。

Step 4: Info.plistファイルをダブル・クリックする。Property List Editorが起動して、Info.plistファイルが開かれるので、以下の項目を変更する。
– CFBundleExectuableを作成するオブジェクトの名に変更する。ここでは、goofyとする。
– CFBundleIdentifierをJavaスタイルでの識別子として名前を変更する。ドメイン名を所有しているなら、それを用いる。ここでは、org.akamatsu.goofyとする。

Step 5: Info.plistファイルを保存し、Property List Editorを終了する。

Step 6: プロジェクト・ファイル(goofy.xcodeproj)をダブル・クリックする。Xcodeが起動し、プロジェクトが開かれる。

Step 7: ソース・リストから、不要なファイルを削除する。ここではmaximum.cを削除する。削除を確認するダイアログが現れるので、「参照を削除」ボタンをクリックする。

Step 8: 自分のソース・ファイル(goofy.c)をプロジェクトに追加する。具体的には、Finderからソース・ファイルをドラッグし、左側のリストのSourceフォルダにドロップすれば良い(右側のリストにはドロップできない)。ファイル追加に関するダイアログが現れるので、そのままOKボタンをクリックする

Step 9: プロジェクト・メニューから「アクティブターゲット’maximum’を編集」を選ぶ。

Step 10: 「”ターゲット”maximum””の情報」ウィンドウが開かれるので、一般タブを選び、名前を変更する。ここではgoofyという名前にする。

Step 11: ビルド・タブを選び、構成メニューから「すべての構成」を選ぶ。そして、コレクション・メニューから「パッケージング」を選び、プロダクト名を変更する。ここではgoofyという名前にする。

Step 12: 以上で設定は完了。ビルド・ボタンをクリックすれば、オブジェクト・ファイルが作られる。

Step 13: オブジェクト・ファイルが作成できれば、Maxを起動してオブジェクトの動作を確認する。Defaultフォルダにgoofy.help(あるいはgoofy-test.patなど)といったテスト用のパッチ・ファイルを作ると良い。

実際のオブジェクト開発では、ソース・コードをいかに記述するかが肝心カナメとなるわけですが、これについてはUBオブジェクト開発講座(3)にて説明。

UBオブジェクト開発講座(1) SDKのインストールとサンプルのビルド

細かなことはさておき、ササっとUB(ユニバーサル・バイナリー)オブジェクトを開発する方法を概観してみます。より詳しい説明はCycling ’74のWEBサイトに 「Max/MSP Universal Binary SDK Documentation」が掲載されていますので、参照してください。ちなみに、Windows用のオブジェクトを開発した経験がないので、誰か書いてくれるとウレシイな。

さてさて、UBオブジェクト開発講座の第1回はSDK(ソフトウェア・デベロップメント・キット)のインストールとサンプルのビルドまで、です。これは「Getting Started」の抄訳を元に多少の補足をしています。

Step 1: Xcodeをインストールする

・UBオブジェクトの開発には、Xcode 2.2.1以降とMac OS X 10.4が必要である。
・XcodeはMac OS XのインストールDVDに付属している他、最新版はApple Computer社の開発者用サイトからダウンロードできる。

Step 2: SDKをコピーする

・ Cycling ’74社のWebサイトからMaxMSP UB SDKをダウンロードする。
・MaxMSP UB SDKフォルダをハードディスクの任意の場所にコピーする。

Step 3: フレームワークをコピーする

・MaxMSP UB SDKフォルダのCopyContentsToLibraryFrameworksフォルダの中身をLibrary/Frameworks/フォルダにコピーする。
(Libraryフォルダは日本語環境では起動ディスクの「ライブラリ」フォルダのこと。)

Step 4: サンプルをビルドする

・サンプルのプロジェクト・ファイルをダブル・クリックする。例えば、MaxMSP UB SDKフォルダのexample-externsフォルダにあるmaximumフォルダのmaximum.xcodeprojファイルをダブル・クリックする。
・Xcodeが起動し、プロジェクト・ウィンドウが開く。
・Xcodeのプロジェクト・ウィンドウのビルド・アイコンをクリックして、プロジェクトをビルドする。
・ビルドが成功すれば、maximumフォルダにbuildフォルダが作られ、その中のDefaultフォルダにmaximum.mxoというオブジェクト・ファイルが作られる。
・何らかのエラーが発生する場合は、MaxMSP UB SDKの構成やフレームワークのコピーが間違っていることが考えられるので、再確認する。
・オブジェクト・ファイルが作成できれば、Maxを起動してオブジェクトの動作を確認する。Defaultフォルダにmaximum.help(あるいはmaximum-test.patなど)といったテスト用のパッチ・ファイルを作ると良い。

Step 5: 自分のプロジェクを変換する

・サンプルのプロジェクトを複製し、それを元にユニバーサル・バイナリ化したい自分のプロジェクト、あるいは新しく制作するプロジェクトを作ると良い。詳しくは、UBオブジェクト開発講座(2)にて説明。