From: "U.Nakamura" Date: 2005-10-25T15:52:04+09:00 Subject: [ruby-dev:27510] Re: [ ruby-Bugs-2613 ] building ruby 1.8.3 on Solaris こんにちは、なかむら(う)です。 In message "[ruby-dev:27509] Re: [ ruby-Bugs-2613 ] building ruby 1.8.3 on Solaris" on Oct.25,2005 15:06:34, wrote: | |VC++環境でコンパイルされたRubyで、MinGW環境でコンパイルされた | |拡張ライブラリをロードすることはできます。 | |MinGW環境でコンパイルされたRubyで、VC++環境でコンパイルされた | |拡張ライブラリをロードすることもできます。 | | | |VC++環境で作成されたヘッダやライブラリを流用してMinGWで拡張ラ | |イブラリを作成すること(今回の例)はできません。 | |MinGW環境で作成されたヘッダやライブラリを流用してVC++で拡張ラ | |イブラリを作成することもできません。 | | |と、いうことなのですが、英語かあ... | | 私が訳しても良いのですが、もうちょっと教えてください。 まつもとさんの手を煩わせるかどうかは後で考えるとして... | 拡張がロードできるのに、ライブラリを「流用」できないという状 | 況を説明できる自信がありません。 「拡張ライブラリ」はロードできるけど、「ヘッダやライブラリ」 は流用できないわけですが、後者の「ライブラリ」は「インポート ライブラリ」であって「拡張ライブラリ」ではありません。 言葉足らずですみませんです。 # やっぱ「拡張モジュール」と呼ぶべきか? 以下、具体的な説明。 まず、ruby本体であるダイナミックリンクライブラリ(以下DLL) msvcrt-ruby18.dll が存在します。 これはUNIXぽい環境で--enable-sharedでrubyを作成した時の、 libruby.so.1.8 とかいうものに大体相当します。 一方、元の人が作ろうとしている拡張ライブラリ my_test.so があります。 my_test.soは中でrb_cObjectを使用しているので、実行時にはruby 本体の中にあるrb_cObjectを参照しなければいけません。 さて、Windows環境下では、DLL内のシンボルを参照するプログラム を作成する場合、構築時にインポートライブラリというものをリン クしなければいけません。 インポートライブラリの中にはDLL内の公開シンボルの情報が含まれ ていて、リンカはそれを参照して、プログラム実行時に正しく動的 リンクが解決されるようにバイナリを生成します。 ただし、VC++とMinGWとではオブジェクトファイル/ライブラリのフ ォーマットに互換性がないので、インポートライブラリを相互に流 用することはできません。 ここで、元の人は、VC++用のruby本体DLLのインポートライブラリを 持ってきて、reimpというMinGWのユーティリティを使って、インポ ートライブラリをMinGW用に変換しています。 しかし、reimpによる変換はどうやら完璧ではないらしく、正しいイ ンポートライブラリを生成できていません。 よって、この正しくないインポートライブラリを使って構築した拡 張ライブラリ my_test.so は、実行時に正しく動的リンクが解決さ れないので正常には動作しません。 | 先方は「declspecを追加すれば動くんだから」と言っていて、それ | はそれで分かる気がするんです。そこを「できない」というからに | は「あなたの環境では動くけど、別の状況でxxxの問題が起こるか | らその変更はできない」といってあげた方が良いと思うですが、そ | の「xxxの問題」ってどんなもんなんでしょう? | | 山本さんの返答には「extensionをstatic linkできない」って書い | てあったように思うのですが、それだけだったらdynamic linkでき ebanさんの返答ですね([ruby-dev:27494])。 | る方が重要な気もしますし、新たにstatic linkしていることを示 | すシンボルを導入することで対処できそうな気がします(static | linkとdynamic linkで同じオブジェクトファイルを使えなくちゃい | けない保証はしていないし)。あるいはもっと本質的な問題がある | のなら、それはそれで説明しなくちゃいけませんし。 私も完全にMinGW版の事情を理解しているわけではないのですが、ruby 本体DLLを作成する時とruby本体DLLをリンクする何かを作成する時 でdllimportをつけるかどうかを変えないといけない、という問題だ ったと思います。 dllimportなし + staticリンク -> OK dllimportあり + staticリンク -> NG dllimportあり + dynamicリンク + 正しいインポートライブラリ -> OK dllimportあり + dynamicリンク + 不正なインポートライブラリ -> OK dllimportなし + dynamicリンク + 正しいインポートライブラリ -> OK dllimportなし + dynamicリンク + 不正なインポートライブラリ -> NG というわけで、dllimportなしにして正しいインポートライブラリを 利用できるようにしておけば、staticだろうがdynamicだろうがうま くいくわけで、MinGW版は現状このように提供されているはずです。 今回はわざわざ不正なインポートライブラリを自分で作ってそれを 利用しようとしてるのがだめ、と。 それでは。 -- U.Nakamura