2009年5月7日木曜日

Windows起動時にhal.dllが見つかりませんと言われた場合の対処法

久しぶりにBootCampでWindows XPを起動しようとしたら、hal.dllが見つかりませんといった具合のエラーメッセージが表示されてうんともすんとも言わなくなってしまいました。dllが破損したのかと思い調べてみたところ、このエラーメッセージはC:¥boot.iniファイルの設定が破損された場合に表示されるメッセージだと言うことが分かりました(さすがマイクロソフト、エラーメッセージの意味不明さには定評があります)。なるほど、確かにboot.iniファイルが消えてました。

修復するにはWindows XPをCDから起動して、回復コンソールを立ち上げます。画面の表示に従えば大丈夫だと思います。
回復コンソールが起動したら、以下のコマンドを入力。
bootcfg /list

これで起動設定(boot.iniファイルの中身)の一覧が表示されます。私の場合は、boot.ini自体が存在しないので、設定がありませんと怒られてしまいました。
設定が破損しているのを確認したら、以下のコマンドで修復を行います。
bootcfg /rebuild

途中、3回ぐらい選択肢が表示されますが、以下のように回答します。
インストールをブート一覧に追加しますか?
YES

ブートIDを入力してください
適当でかまいません。MacでBootCampしている私の場合はWindowsと入力しました。普通のWindowsマシンの場合にはWindows XP Professionalとか入れておくとわかりやすいのではないでしょうか。

オプションを指定してください
/fastdetect

これで完了です。あっさり終了するのでちょっと拍子抜け。あとはコンピューターを再起動すれば問題なくWindows XPが起動すると思います。

2009年5月4日月曜日

Objective-CのnilとNULLの違いって何?

自分用メモ。
nilは「Objective-Cの空のオブジェクト」、NULLは「C言語の空ポインタ」と解釈する。もっとも良い例がNSFileManagerのcreateDirectoryAtPath:withIntermediateDirectories:attributes:error:です。
http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/createDirectoryAtPath:withIntermediateDirectories:attributes:error:

リファレンスを読んでみると、attributes:の指定が不要なときはnilを、error:の指定が不要なときはNULLを引数として与えろと明示的に書かれています。これは、attributes:が(NSDictionary *)型=NSDictionaryのオブジェクトを引数として受け取るのに対して、error:は(NSError **)型=NSErrorのオブジェクトのポインタを引数として受け取るためだと考えられます。といっても私はObjective-CもC言語もド素人ですので、ひょっとしたら大嘘かもしれません。違ってたらごめんなさい><


※追記:やっぱり定義そのものが違った><
すたっくおばふろ曰く(http://stackoverflow.com/questions/557582/null-vs-nil-in-objective-c
えらいひと曰く(http://www.libjingu.jp/trans/clocFAQ-j.html#objects-nil


知らないとついつい全部nilもNULLも同じだろと思いnilって指定してしまいそうですね。おそらくnilを指定しても動くとは思いますが・・・Objective-CとC言語の混ざり合いというか関わり合いがこんなところで垣間見れて面白いです。

Objective-CではJavaのようにNullPointerExceptionが発生したりしない

そう、Objective-CにはNilPointerExceptionのようなものがないんです。
Javaでは
int main(String[] args) {
  String str = null;
  int length = str.length(); //NullPointerException

  // bar()がnullだとNullPointerException
  Object result = Foo.bar().baz().abesi().hidebu();
}
Objective-Cでは
int main(int argc, char** argv){
  NSString *str = nil;
  int length = [str length]; //何も起こらない。lengthにはデフォルト値0が入る

  // barがnilを返したら、後続のbaz, abesi, hidebuもnilを返す。
  id result = [[[[Foo bar] baz] abesi] hidebu];
}

同僚の方(http://twitter.com/ksk_matsuo/status/1682599075)よりこっそり教えていただきました。ありがとうございます!

なんと言ってもJava人にとっていちばん恐ろしいのがこのNullPointerExceptionなのですよ。だからオブジェクトのメソッドを呼び出すときはいつでもオブジェクトがnullだったらどうしようガクブルと思いながらプログラム書いてるわけです。それがいきなり「Objective-Cになったらぬるぽなんてありません安心です^^」なんて言われても安心できないなぁ><