Jun 8, 2008

マニフェスト関連


Visual C++ ファイルの再配布

Visual C++ ライブラリ DLL (MSVCR80.DLL など) に到達できた場合 (アプ
リケーションのローカル フォルダまたはシステム フォルダにインストール
されている場合など)、次のメッセージが表示されます。

R6034 An application has made an attempt to load the C runtime library incorrectly.

C/C++ 分離アプリケーションおよび side-by-side アセンブリのトラブルシューティング

すべての DLL がバイナリに埋め込まれたマニフェストを持つようにすることを
お勧めします。DLL が LoadLibrary 呼び出しで読み込まれる場合、外部マニフェストは
無視されます。

方法 : マニフェストを C/C++ アプリケーションに埋め込む

C/C++ アプリケーション (またはライブラリ) では、そのマニフェストを
最終的なバイナリに埋め込んでおくことをお勧めします。これにより、ほとんどの
シナリオで実行時の適切な動作が保証されます。

wxRuby2


wxWidgets の Ruby バインディング・ wxRuby というものを試そうとしてみました。 利用しているのは One-Click Ruby Installer 1.8.6-26。以下の作業は主に Cygwin Bash シェルで行っています。
インストールは RubyGems で楽勝でした。
$ gem.bat install wxruby
Bulk updating Gem source index for: http://gems.rubyforge.org
Building native extensions.  This could take a while...
Successfully installed wxruby-1.9.7-x86-mswin32-60
1 gem installed
wxRuby 1.9.7 の Windows 版バイナリがインストールされます。
それではさっそくサンプル起動!
$ ruby -rubygems d\:/ruby/lib/ruby/gems/1.8/gems/wxruby-1.9.7-x86-mswin32-60/samples/minimal/minimal.rb
しかしその瞬間、よくありがちなダイアログボックスが登場しました。
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Runtime Error!

Program: d:\ruby\bin\ruby.exe

R6034
An application has made an attempt to load the C runtime library incorrectly.
Please contact the application's support team for more information.

---------------------------
OK   
---------------------------
そしてターミナルにはエラーメッセージが:
d:/ruby/lib/ruby/gems/1.8/gems/wxruby-1.9.7-x86-mswin32-60/lib/wxruby2.so: 1114: ダイナミック リンク ライブラリ (DLL) 初期化ルーチンの実行に失敗しました。
- d:/ruby/lib/ruby/gems/1.8/gems/wxruby-1.9.7-x86-mswin32-60/lib/wxruby2.so (LoadError)
from d:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
from d:/ruby/lib/ruby/gems/1.8/gems/wxruby-1.9.7-x86-mswin32-60/lib/wx.rb:12
from d:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in `gem_original_require'
from d:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in `require'
from d:/ruby/lib/ruby/gems/1.8/gems/wxruby-1.9.7-x86-mswin32-60/samples/minimal/minimal.rb:8
要するに wxruby2.so の LoadError だそうです。見に行きましょう。
$ cd d\:/ruby/lib/ruby/gems/1.8/gems/wxruby-1.9.7-x86-mswin32-60/lib/
$ ls
wx  wx.rb  wxruby2.exp  wxruby2.lib  wxruby2.so  wxruby2.so.manifest
む、wxruby2.so.manifest が。まさか。
$ strings wxruby2.so | grep manifest

$
埋 め 込 ま れ て な い
LoadLibrary される DLL の場合は外部マニフェストが無視されるそうです。最終的なバイナリファイルにはマニフェストの埋め込みが必要となります。
そのようなわけで Visual Studio のコマンドプロンプトから以下の作業をしました:
Setting environment for using Microsoft Visual Studio 2008 x86 tools.

D:\Programs\Microsoft Visual Studio 9.0\VC>cd D:\ruby\lib\ruby\gems\1.8\gems\wxruby-1.9.7-x86-mswin32-60\lib

D:\ruby\lib\ruby\gems\1.8\gems\wxruby-1.9.7-x86-mswin32-60\lib>mt -manifest wxruby2.so.manifest -outputresource:wxruby2.so;2
確かめてみましょう。元の Cygwin ターミナルから:
$ strings wxruby2.so | grep manifest
無事に埋め込まれた模様。ではあらためて!
$ ruby -rubygems d\:/ruby/lib/ruby/gems/1.8/gems/wxruby-1.9.7-x86-mswin32-60/samples/minimal/minimal.rb


うまくいきました。