2009年4月2日木曜日

【Windows】Eclipse3.4.2(Ganymede)+PDTでZendDebuggerを使う

WindowsでApache2.0でPHP5.2が動作して、Eclipse GanymedeにPDTが組み込まれているという環境で、ZendDebbuggerを組み込む方法についてです。Webサーバーとデバッグするマシンは同じである必要はありません。

ApacheにZendDebuggerを組み込む

ZendDebuggerの入手
http://downloads.zend.com/pdt/server-debugger/にいく。ZendDebugger-5.2.xx-cygwin_nt-i386.zipをダウンロードする(基本的には最新版でよいはず)。
インストール
Zipを展開すると?_?_x_compのようなフォルダがあるが、最初の2つの数がPHPのバージョンを意味しているので5_2_x_compか5_2_x_nts_compのいずれかのフォルダにあるDLLをどこかにコピーする(展開されたフォルダーごとどこかにおいてもよい)。
5_2_x_compと5_2_x_nts_compの違いは、スレッドセーフか非スレッドセーフであり、どちらを組み込むかは、PHPのビルドによって異なる。phpinfo();で出力された中に「Thread Safety」という項目が「enable」で「Debug Build」が「no」であれば、スレッドセーフであり、いずれかがそうでなければ非スレッドセーフということになる。PHPをバイナリでインストールした場合には、スレッドセーフになっているはず。
php.iniの設定
以下の設定をphp.iniに追加する。
zend_extension_ts=<コピーしたDLLのパス>ZendDebugger.dll
zend_debugger.allow_hosts=<アクセスを許可するIPアドレス>
zend_debugger.expose_remotely=always
もし非スレッドセーフなDLLを組み込むときは、「zend_extension_ts」は「zend_extension」となる。
IPアドレスの設定は、複数ある場合カンマ「,」で区切る。
dummy.phpのコピー
展開されたフォルダにあるdummy.phpをApacheのドキュメントルートにコピーする。このファイルは、PDTのデバッグの設定で「TestDebugger」で接続テストをするときにアクセスする。本質的には必須ではない。

設定完了後にApacheを開始または再起動し、エラーログをチェックする。

Eclipseの設定

Webサーバーの設定
Eclipseの設定ダイアログ(Preferencesで表示される)の「PHP」の「PHP Servers」の項目を表示して、デバッグのターゲットとなるWebサーバーを指定する。
または、「PHP」か「PHP Debug」のパースペクティブを表示にあるデバッグのダイアログ(Debug Configurationで表示される)を表示して、「PHP Server」をいう項目を変更または追加する(デフォルトはlocalhostになっている)。
接続の確認
上記のデバッグのダイアログで「Test Debugger」というボタンを押すと接続確認ができる。ただし、dummy.phpをドキュメントルートにコピーしておかないとテストはできない。
デバッグファイルの設定
デバッグのダイアログで、対象となるファイルを指定する。ここでは、ローカルなファイルを指定するので、普通はプロジェクトのフォルダからの相対パスとなる。
ドキュメントルートからのパスの関係がプロジェクトのパスと一致していれば、URLの設定は「Auto Generate」でデバッグできることになる。すなわちこれは、Apacheのドキュメントルート上にPHPのプロジェクトを作成したという状態を意味している。
デバッグの確認
あとは、デバッグのダイアログで「Debug」ボタン(Runの設定の場合「Run」ボタン)を押すとApache上で実行される。
このとき、表示をEclipse上ではなく別のブラウザ上に表示することができる。設定するには、PHPのパースペクティブで、「Window」のメニューで「Web Browser」で変更するか、設定ダイアログの「General」の「Web Browser」で変更することができる。

2008年12月16日火曜日

[VC++ 2008 Express] Formのnamespaceを変更するとランタイムエラーが出る

VC++ 2008 Express Editionでフォームアプリケーションを作成すると、formのソースコードにnamespaceが定義される。このnamespaceはプロジェクト名になっているのであるが、変更したくなることもあるだろう。

namespaceを変更してもビルドも成功するのであるが、実行時に「指定されたカルチャまたはニュートラル カルチャに対して適切なリソースが見つかりませんでした。…」のようなエラーが発生する。
このエラーの発生しているのは、formのなかでリソースを読み取るところ、実際のコードでは「System::ComponentModel::ComponentResourceManager^ resources = …」となっている場所になる。

なぜエラーになるかというと、ComponentResourceManagerを作成するところで、typeidをベースに読み取るのであるが、typeidはnamespaceに依存する。すなわち、<namespace>.<クラス名>となっている。
しかしながら、コンパイルされたリソース(マネージリソース)は、ソースコードで変更されたnamespaceが反映されないため、ランタイム時にリソースを読み込むことができずエラーとなるという仕組みなようだ。

そこで、マネージリソースのコンパイル設定を変えればうまくいくはずで、プロジェクトのプロパティでは、リソースファイル名の設定が「$(IntDir)\$(RootNamespace).$(InputName).resources」となっている。
すなわち、「$(RootNamespace)」の部分が変更したnamespaceになっていればよいということになる。

ひとつの解決方法としては、RootNamespaceの値の参照をやめて、変更したnamespaceに変えてしまうというのがある。要するに「$(RootNamespace)」を書き換えるということである。

どうせなら、RootNamespaceの値を変更したほうがよさそうだと思うのだが、IDE上で変更できそうな画面が見つからない。仕方がないので、プロジェクトの定義ファイル(.vcproj)をテキストエディタで変更する。変更箇所は簡単に見つかるはずで、RootNamespace="…"となっているところを書き換える。

といっても、ある意味無理やり変更しているので、IDE上でなんだかの不都合が生じる可能性もあるので、あくまでも自己責任の範囲でやってみてください。