MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第230号

2006-11-28

目次

  • 「「Wonderful Server Life」   第28回  田畑 英和
  • 小池邦人の「Carbon API 徒然草」
  • SqueakではじめるSmalltalk入門  第74回  鷲見 正人
  • ニュース・解説               木下 誠

「Wonderful Server Life」  第28回  田畑 英和

■  〜Xserve編〜

 前回チラリとご紹介した新型Xserveですが、ようやく出荷が始まったようですので、今回は予定を変更して新型Xserveについてレポートしたいと思います。
 まずこれまでの経緯ですが、今年の8月に開催されたWWDCでPower Mac G5の後継機となるIntel Xeonプロセッサを搭載したMac Proが発表になりました。Mac Proはすぐに発売開始となりましたが、同じ日に発表された新型XserveはWWDCの時点では10月発売開始予定とアナウンスされていました。
 10月発売予定と聞いてしばらく間隔があるので「ヤバイかも」と思ったのは私だけではないと思いますが(笑)、まず新型Xserveの発表後にそれまで販売されていたXserve G5の在庫が徐々になくなっていきました。つまりXserveが欲しくても入手しづらい期間ができてしまったということです。これはサーバ機にとってはちょっと致命的な問題ですね。システムの稼働スケジュールを調整したり、場合によってはアップル製以外のサーバ機を検討しなくてはならなくなります。
 特にMac OS X Serverではオープンソース系のソフトが全面的に採用されていますから、手間と時間さえかければ同様のサービスはほかのプラットフォームでも実現できてしまうわけです。そこに品がないということになれば、いくらコストパフォーマンスや使い勝手がよかったとしても時間的な問題により採用計画からは外さねばならないケースも出てしまいます。
 発売が予定されていた10月になってからですが、いっこうに発売が開始される気配がなく、10月下旬になってからようやく注文が受け付けられ、11月も下旬にさしかかろうとしたときにようやく出荷が開始されました。
 さいわいオンラインのApple Storeを見てみますと出荷予定日は「24時間以内」となっておりますので、供給体制は整っていることが期待できますが、Xserveは過去にもモデルチェンジの時期に入手できない空白時期が発生していたので今後は2度とこういったことはやめていただきたいものです。

なんだかネガティブな話題から始まってしまいましたが、新しくモデルチェンジしたXserveのスペックについてみていきたいと思います。
 まずこれまでは3種類の基本構成が用意されていましたが、モデルチェンジに伴い基本構成は1種類になりました。基本構成が1種類なのはMac Proも同様ですね。またCPUもMac Proと同様のIntel Xeonプロセッサが搭載されています。具体的な基本のシステム構成と価格は次のとおりです。

・基本システム構成:
 CPU:2.0GHz 64ビットデュアルコアIntel Xeonプロセッサ×2基
 メモリ:1GBメモリ(667MHz DDR2 Fully Buffered DIMM、ECC機能付き)
 HDD:80GB 7200-rpm 3Gbps シリアルATA ハードディスクドライブ×1基
 グラフィックカード:ATI Radeon X1300(64MBビデオメモリ搭載)
 OS:Mac OS X Server 10.4 Unlimitedクライアント版
 価格:379,800円

 これまでのXserve G5から大きく変わったところはやはりCPUがPowerPC G5からIntel Xeonプロセッサになったことです。クロックも最大で3.0GHzまでカスタマイズ可能になっており、パフォーマンスの向上が見込めます。アップルが公開している資料によれば最大約5倍のパフォーマンス向上が見込めます。
 最近は性能をアピールするのにワットあたりのパフォーマンスが評価されていますが、ちなみに新型Xserveの消費電力は650Wとなっています。

・パフォーマンスについて
http://www.apple.com/jp/xserve/intelxeon.html

 筐体はいままでどおりの19インチラックにおさまる1Uの筐体ですが、奥行きが5cmほど長くなり76.2cmになっています。コンパクトなラックをすでに使用しているケースではラックにおさまるかを事前に確認する必要があります。
 またこれまではグラフィックカードは拡張スロットに追加するか、あるいはグラフィックカードなしのヘッドレスな状態で運用する仕様でしたが、新型のXserveでは標準でグラフィックカードが内蔵されています。拡張スロットを使わずにオンボードで用意されていますので、グラフィックコントローラを使用したとしても、拡張スロットが2基使用可能な状態になります。
 ネットワークはギガビットEthernetがこれもオンボードで2基搭載されています。

基本構成は1種類だけですが、Apple Store(Online)上では様々なカスタマイズが可能ですので、どのようなカスタマイズが可能かをみていきましょう。

□CPU
 標準では2.0GHzのデュアルコアIntel Xeonが2基搭載されています。つまりクアッドコア構成になっています。クロックは標準構成も含め以下の3通りから選択可能です。()内は構成を変更したときのApple Store差額です。

 2.00GHz x2
 2.66GHz x2(プラス102,060円)
 3.00GHz x2(プラス229,950円)

□メモリ
 8基のDIMMスロットが用意されています。標準構成では512MBが2枚ですが、最大で4GBを8枚搭載できますので32GBまでメモリを増設することができます。ただし32GB増設するには2,986,200円の追加費用が必要になりますので、よっぽど大量のメモリを必要とするケースでしか32GBの構成はかえって費用効果が悪いでしょう。これだけの価格があれば標準構成のXserveがもう何台か購入できてしまいますから。
 なおメモリを増設するにはバンド幅を活用するために4枚構成もしくは8枚構成での追加が選択可能になっています。

□HDD
 標準構成でHDDは1基のみですが、追加で最大3基までHDDを搭載できます。ディスクのタイプはSerial ATA(7,200rpm)と、より高いパフォーマンスが実現できるSAS(15,000rpm)のどちらかを選択できます。それぞれのタイプで選択可能なディスク容量は以下のとおりです。標準の80GBで足りない場合はSASタイプのものを選択するか、Serial ATAで500GBに変更することになります。

 Serial ATA(7,200rpm):80GB/500GB
 SAS(15,000rpm) 73GB/300GB

 Xserve G5ではハードウェアのRAIDコントローラを拡張スロットに追加できましたが、新型XserveではハードウェアのRAIDコントローラが用意されていませんので(内部のレイアウトも変更になっています)、RAIDを使用する場合はソフトウェアRAIDにするか、Xserve RAIDなどの外付けのRAIDストレージを別途用意する必要があります。

□光学式ドライブ
 最大24倍速のComboドライブ(標準)か、最大8倍速の2層式に対応したSuper Driveが選択できます。

□内蔵グラフィック
 ミニDVI出力端子付きのグラフィックカードがあらかじめ内蔵されており、23inchのCinema Displayまで対応しています。内蔵グラフィックカードをなしにして価格をおさえることもできますが、差額は6,300円しか違いませんのでそのままつけておいたほうが便利でしょう。

□拡張スロット
 PCI Expressの拡張スロットが2基用意されており、グラフィックカードが内蔵になったことから、2基とも活用することができます。拡張スロットにはギガビットEthernetカード、SCSIカード、Fiber Channelカードなどが選択できます。
 2基ある拡張スロットはそれぞれ細かな仕様が異なりますので、拡張スロットを利用する場合には事前に仕様をしっかりと確認しておきましょう。

□電源オプション
 新型Xserveでは電源ユニットを2基搭載できるようになりました。標準で電源ユニットは1基だけですが、オプションで2基目の電源ユニットを追加できます。電源ユニットはホットスワップに対応していますので、電源ユニットを2基使用している場合には本体の電源を入れたままで片方の電源ユニットを交換することができます。システムの停止時間を極力短くしたい場合には検討すべきオプションになります。

□ラックマウントキット
 今回のモデルチェンジでラックへのマウントキットは「角穴タイプ」と「ねじ穴タイプ」の2種類から選択するようになりました。これは購入時にどちらかを選択する必要がありますので、事前にラックを確認して適切な方を選択しましょう。

□Apple Care
 以上がApple Storeで選択可能な主なオプションですが、他にもApple Storeの保守契約があります。予備のパーツをあらかじめ取り寄せておく「AppleCare Service Parts Kit for Xserve」や、電話/E-mailによるサポートおよび出張修理サービスがうけられる「AppleCare Premium Service and Support Plan」が提供されています。それぞれの具体的なサービス内容は次のURLを参照してください。

http://www.apple.com/jp/support/products/partskits.html
http://www.apple.com/jp/support/products/premium.html

 出荷の遅れという問題はありましたが、これでようやくすべての製品がIntel対応したことになります。1年前はまだすべての製品がPower PCだったことを考えるとこれはすごいことですね。
 さて、次回は前回の続きでネットワークホームの設定方法について解説したいと思います。

つづく

小池邦人のCarbon API 徒然草

● Carbon API 徒然草(2006/11/24)

〜 Carbonモダンアプリケーションへの道(その7) 〜

アプリケーションを多国語対応にする場合、Shift-JISコードで表記できない文字列を用意する必要が出てきます。そこで登場するのがユニコードです。今回はユニコードを操作するAPIについて、その特徴や活用方法などを解説したいと思います。

まずはソースコード内で頻繁に使うユニコードデータの保存用構造体を決めます。つまりPascalストリングスならStr255、Cストリングスなら前回紹介したCStr255構造体に相当するものです。独自に定義してもよいのですが、筆者はFile ManagerのAPIで利用されているHFSUniStr255構造体を用いています。この構造体はFiles.hヘッダーファイルで定義されています。

struct HFSUniStr255 {
UInt16 length; // ユニコード文字列の長さ
UniChar unicode[255]; // ユニコード文字列データ
};

構造体で利用されているUniCharは別の場所でUInt16として定義されています。ここに記載されているUInt16はunsigned shortの事です。つまり1文字のデータが2バイトということになります。また、長さは65535文字まで設定できますが、UniCharの配列が255しか確保されていませんので、文字列長のオーバーフローには注意が必要です。この構造体のサイズ(sizeof(HFSUniStr255))は512バイトとなります。今回も、CStr255を定義した場合と同様に、以下のように格納文字長だけが異なる構造体(HFSUniStr63、HFSUniStr31、HFSUniStr15など)をいくつか用意しておくと便利です。

typedef struct  {
                    UInt16   length;
                    UniChar  unicode[63];  // 63文字まで格納可能
                } HFSUniStr63;

typedef struct  {
                    UInt16   length;
                    UniChar  unicode[31];  // 31文字まで格納可能
                } HFSUniStr31;

typedef struct  {
                    UInt16   length;
                    UniChar  unicode[15];  // 15文字まで格納可能
                } HFSUniStr15;

HFSUniStr255にユニコード文字列を格納し、各種APIや自作ルーチンに渡す場合に注意することがあります。HFSUniStr255のワードデータはPowerPC環境ではビッグエンディアンで、X86環境ではリトルエンディアンで保存されています。よって、この構造体を一度外部ファイルへ書き出し、異なるエンディアン環境のユニバーサル・アプリケーションで読み込む場合には、エンディアンをひっくり返す必要があります。もしアプリケーションのネイティブ・ファイルフォーマットをビッグエンディアン(PowerPC)とするならば、x86環境で読み込んだ場合には、以下のようなスワップルーチンを通すことになります。

void flipHFSUniStr255( lHFSUniStr255 *ustr )
{
    long    i;

    ustr->length=Endian16_Swap( ustr->length );  //  文字列長をスワップ
    for( i=0;ilength;i++ )                //  文字データをスワップ
           ustr->unicode[i]=Endian16_Swap( ustr->unicode[i] );
}


文字の処理中に、ユニコード文字列をCFStringRefに変換したり、CFStringRefをユニコード文字列に変換したりする作業が発生した場合には、以下の2つのFile Manager APIを用いると便利です。ユニコードからCFStringRefを得るにはFSCreateStringFromHFSUniStr()を…

CFStringRef FSCreateStringFromHFSUniStr( CFAllocatorRef alloc,
                                            const HFSUniStr255 *uniStr);

逆に、CFStringRefからユニコードを得るにはFSGetHFSUniStrFromString()を使います。

OSStatus FSGetHFSUniStrFromString( CFStringRef theString,
                                                   HFSUniStr255 *uniStr);

また、これらのAPIと同じ働きを持つルーチンをCore FoundationのAPIを利用し作成すると、以下のような感じになります。cfToUnicodeString()がCFStringRefからユニコード文字列への変換、unicodeToCFString()がユニコード文字列からCFStringRefへの変換を行います。

SErr cfToUnicodeString( CFStringRef cfstr,HFSUniStr255 *ustr )
{
    short        err=1;
    CFRange        range;

    if( ustr->length=CFStringGetLength( cfstr ) )   // 文字列の長さを得る
    {
        if( ustr->length > 255 )                    // 255文字以上はカット
            ustr->length=255;
        range=CFRangeMake( 0,ustr->length );
        CFStringGetCharacters( cfstr,range,ustr->unicode );  // 文字列変換
        err=noErr;
    }
    return( err );
}

OSErr unicodeToCFString( HFSUniStr255 *ustr,CFStringRef *cfstr )
{
    short    err=1;

    if( *cfstr=CFStringCreateWithCharacters( NULL,ustr->unicode,ustr->length ) )
        err=noErr;
    return( err );
}

さて、話をアプリケーションの多国語対応に戻しましょう。Core Foundationには、ユニコード文字列を外部ファイルから読み込み自作アプリケーションで利用するのに最適なAPIが用意されています。以下のCFCopyLocalizedString()です。このAPIはCFBundle.hヘッダーファイルに定義されています。

CFStringRef CFCopyLocalizedString( CFStringRef key,const char *comment );

CFCopyLocalizedString()を利用するには、先んじて、アプリケーションで使うユニコード文字列を列記した「Localizable.strings」というファイルを、アプリケーションパッケージの「Resouces」フォルダ内の各言語対応フォルダに入れておく必要があります。例えば、英語用であれば「English.lproj」、日本語用ならば「Japanese.lproj」フォルダ内です。Finderの情報ウィンドウに各国語でバージョン番号等を表示させるために用意する「InfoPlist.strings」ファイルと同じ仕組みです。このAPIが、CFString.hではなくCFBundle.hに定義されているのは、利用形態が「パッケージ」の仕組みに深く関わっているのが理由です。

各国語用のLocalizable.stringsファイルは、Xcodeプロジェクトのファイル一覧に登録しておくことにより、リンク時にアプリケーションパッケージ内の適切なフォルダに格納されます。まず最初のサンプルとして、Apple社から提供されている「iPhoto」の日本語用Localizable.stringsを調べてみることにします。このファイルには恐ろしく大量の文字列が列記されていますが、最初の数行を見てみると…

AppName = "iPhoto";
VersionFormat = "%1$@ (%2$@)";          // for example, "4.0d8 (150)"
AboutFormat = "バージョン %2$@";        // AppName VersionFormat
MediaBrowser = "Aperture ライブラリを表示...";


となっています。最初の1行は、CFCopyLocalizedString()の最初の引数にキーワードとしてAppNameを渡せば、”iPhoto”というユニコード文字列がCFStringRefとして返ってくることを意味しています。ちなみに、2番目の引数は翻訳用コメントを記載しておく場所であり処理自体には何も意味を持ちません。キーワード側もCFStringRefである必要がありますので、以下のように記載すれば目的は達成されます。

CFStringRef    cfstr;
HFSUniStr255   ustr;

cfstr=CFCopyLocalizedString( CFSTR( "AppName" ),"" );
FSGetHFSUniStrFromString( cfstr,&ustr );

同様に、4行目のキーワードのMediaBrowserを渡せば、日本語ユニコード文字列として”Aperture ライブラリを表示…”が返ってくるわけです。

cfstr=CFCopyLocalizedString( CFSTR( "MediaBrowser" ),"" );

今回取り上げたLocalizable.stringsサンプルの2行目には、返す文字列の中に「%1$@」といった表記があります。これは、どんな意味を持つのでしょうか?
 次回は、さらに詳しくLocalizable.stringsの表記の仕組みを解説したいと思います。

つづく

SqueakではじめるSmalltalk入門   第74回  鷲見 正人

本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、製作中の簡易GUIビルダにおいて、扱うことができるウィジェットの種類を増やす拡張を施す際、メソッド定義のコピーをせずともそれができる仕組みを考えます。

テキストフィールドをウインドウに追加するためのメソッドは次のようなものでした。

addFieldTo: window
   | field relFrame |
   field := PluggableTextMorph
      on: self text: nil accept: nil readSelection: nil menu: nil.
   relFrame := (Rectangle fromUser
      scaleFrom: window layoutBounds
      to: (0 asPoint extent: 1e3 asPoint)) scaleBy: 1.0e-3.
   window addMorph: field frame: relFrame

前回は、ボタンを追加するためのメソッド「#addButton:to:」を、この#addFieldTo:の必要な部分を書き換えることで定義したのでしたね。しかし、新しいウィジェットを扱えるようにするたびに、似たようなメソッドの複製が増えてゆくことは避けるべきです。

そこで、どんなウィジェットでも利用できる汎用のウィジェット追加用メソッドがどんなものであればよいのかを考えます。この新しいメソッドは、ウィジェットの種類を#fieldや#buttonなどといったシンボル(widgetSym)で与えることにして、「add: widgetSym to: window」というメッセージで起動できるメソッド「#add:to:」であると想定します。#addFieldTo:と#addButtonTo:の共通部分を抽出して、#add:to:の定義は(まだ完全ではありませんが…)次ように書くことが可能です。

add: widgetSym to: window
   | widget relFrame |
   widget ":= この部分をどう書くか? ".
   relFrame := (Rectangle fromUser
      scaleFrom: window layoutBounds
      to: (0 asPoint extent: 1e3 asPoint)) scaleBy: 1.0e-3.
   window addMorph: widget frame: relFrame


ちなみに、この擬似的なメソッド定義はもちろん動作はしませんし、コンパイル時に警告も出ますが、コンパイル(accespt (cmd + S))それ自体は通るので、コピー&ペーストで登録作業を済ませてしまってかまいません。こうした良い意味で“ルーズ”なところはSmalltalkもObjective-Cとよく似ていますね。

さて。問題は、この疑似コードの一行目の「この部分を…」でwidgetSymで指定したシンボル(#field、#button)からウィジェットそのものを作って返すような式を書くことです。

まず、ウィジェットを表わすシンボルと同名で、起動すると、それぞれの名前が示すウィジェットを作成して返してくるメソッドを定義しましょう。次の二つのメソッドを別々にシステムブラウザにコピー&ペースト後、accept (cmd+ S)してください。

field
   ^ PluggableTextMorph
      on: self
      text: nil
      accept: nil
      readSelection: nil
      menu: nil

button
   ^ (PluggableButtonMorph
      on: self
      getState: nil
      action: nil) label: 'button'; yourself


これらのメソッドは通常、「self field」とか「self button」というメッセージ式を記述して起動します。しかし、メッセージを動的に送信するためのメソッド「#perform:」を用いることで、次のような記述も可能です。

s

elf perform: #field
self perform: #button

パラメータ部分を変数widgetSymにすれば、次のよう書き直せます。

self perform: widgetSym

冒頭の#add:to:の問題の箇所をこの式で“穴埋め”しましょう。

add: widgetSym to: window
   | widget relFrame |
   widget := self perform: widgetSym.
   relFrame := (Rectangle fromUser
      scaleFrom: window layoutBounds
      to: (0 asPoint extent: 1e3 asPoint)) scaleBy: 1.0e-3.
   window addMorph: widget frame: relFrame


実際に、システムブラウザの#add:to:も、このように書き換えてから、あらためてaccept (cmd + S)してください。

仕上げに#addModelItemsToWindowMenu:も、これまでの#addFieldTo:や#addButtonTo:の代わりに、新しく定義した#add:to:を使ったものに書き換えましょう。パラメータがこれまでのwindowから、widgetSym、windowの二つに増えたので#add:target:selector:argumet:の代わりに、#add:target:selector:argumentList:を用います。

addModelItemsToWindowMenu: aMenu
   | window |
   window := aMenu defaultTarget.
   aMenu addLine.
   aMenu
      add: 'add field'
      target: self
      selector: #add:to:
      argumentList: {#field. window}.
   aMenu
      add: 'add button'
      target: self
      selector: #add:to:
      argumentList: {#button. window}.
   aMenu addLine.
   aMenu add: 'delete' target: self selector: #removeWidgetFrom: argument: window


#addField:to:、#addButtonTo:はもはや無用ですので、削除してしまってかまいません。メソッドの削除は、右上のペインで削除したいメソッドを選択した状態で黄ボタンメニューから「remove method」を選択します。

[fig.A]不要となったメソッドの削除操作

この仕組みにより、ウィジェットの登録の手続きは#add:to:に集約できたので、懸案だったメソッドの複製をして同じようなコードを分散させる心配もなくなりました。

次回はさらに一歩踏み込んで、Smalltalkの強力な動的性とリフレクション機能を最大限に活用し、ウィジェットの種類を増やすときにウィジェット生成のメソッドを登録するだけで済ませることができる(つまり、新たなウィジェット用のメニュー項目の追加も自動的に行なわれる…)ようなカラクリに挑戦してみましょう。

バックナンバー:

ニュース・解説

 今週の解説担当:木下 誠

———————————————————————-
QAが4つ追加
———————————————————————-

先週は、アメリカがThanks Ginvingであったこともあり、めぼしいニュースやドキュメントの追加はほとんどありませんでした。

そんな中、QAがいくつか追加されていたので、それを紹介しましょう。

まず、テンポラリファイルを作成して、それをすぐ削除するためにFSDeleteObjectを呼ぶと、ときたまそれが失敗する問題について。これは、ファイルを作成するとSpotlightのインデックス化や、ウィルス対策ソフトが発動するために起こります。それをさけるには、Spotlightのインデックス化が起こらないフォルダ(たとえば/tmp)に、テンポラリファイルを作るようにします。

QA1497: FSDeleteObject fails with fBsyErr, sometimes
http://developer.apple.com/qa/qa2006/qa1497.html

次に、Securityフレームワークが返すエラーコードについて。このフレームワークのエラーコードは、OSStatusエラーのもの、UNIXスタイルのエラーコードのもの、Common Security Services Manager (CSSM)で定義されているもの、に分類されます。

QA1499: Security Framework Error Codes
http://developer.apple.com/qa/qa2006/qa1499.html

3つめは、Core AudioのAudioConverterが提供する、StdAudioダイアログについて。kQTSCAudioPropertyID_CodecSpecificSettingsArrayプロパティが何を意味しているかを解説しています。

QA1390: Standard Audio – The CodesSpecifiecSettingsArray and MagicCookie properties
http://developer.apple.com/qa/qa2006/qa1390.html

最後は、Web KitプラグインをSafariで動かすときに、それをデバッグする方法について。プラグインのプロジェクトで、カスタム実行ファイルをSafariにしてやります。これは、Web Kitプラグインに限らず、プラグインスタイルのソフトウェアの開発に応用できそうですね。

QA1500: Debugging a Web Kit Plug-in in Xcode
http://developer.apple.com/qa/qa2006/qa1500.html

 ◇MOSAからのお知らせと編集後記は割愛します◇

 MOSA Developer News   略称[MOSADeN=モサ伝]
      記事投稿受付 http://www.mosa.gr.jp/topics/mdn-toukou.html
Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2006 MOSA. All rights reserved.