C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: libファイルがどのVS(.NET)で作成されたか知る方法


(過去ログ 108 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■64454 / inTopicNo.1)  libファイルがどのVS(.NET)で作成されたか知る方法
  
□投稿者/ howling (122回)-(2012/12/04(Tue) 11:37:54)

分類:[.NET 全般] 

お世話になっております。

VS2010 / C# & C++/CLI / Windows7 64bitにて開発を行っております。
(が、今回は開発環境関係無いです。)

前スレからの内容なので、一応リンク先貼っておきます。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=64335

XlenとXranの2か所にて外部参照エラーが発生する件があったのですが、
これはVisualStudio2010(.NET4.0)以降でコンパイルした物と、
VisualStudio2008(.NET3.5)以前でコンパイルした物とが混在した場合に発生するエラーのようです。

そこで、自分自身のプロジェクトをコンパイルする時のバージョンがどれか?というのはプラットフォームツールセットを確認すれば良いとして、
プロジェクトからリンクする静的リンクライブラリ(.lib)が、どのバージョンでコンパイルされた物なのか知る術は無いのでしょうか?

昨日の時点で、どうにか探り探り2008でコンパイルされたlibを見つけ、問題自体は修正したのですが、
できればパッと見でこれを見つける方法があったのか知りたいです。

なお、同様にして、
「コード生成」の「ランタイムライブラリ」が何に指定されているのか?というのも、
もし簡単にわかるようなツールなどご存知でしたら、教えて頂けませんでしょうか?

MTとMDを混ぜてリンクしてしまった場合なども、結構よく発生する問題ですので…。

以上
宜しくお願い致します。

引用返信 編集キー/
■64456 / inTopicNo.2)  Re[1]: libファイルがどのVS(.NET)で作成されたか知る方法
□投稿者/ 774RR (27回)-(2012/12/04(Tue) 12:23:56)
既にあるとおり CLI 配下の「あせんぶり」だと、原則 .LIB を使う必要は無いので
.LIB の「作ったコンパイラ」バージョンなるものが必要になる、としたら
- C++, C++/CLI などで作ったインポートライブラリ (対応する .DLL がある)
- C++, C++/CLI などで作った純粋静的ライブラリ (.LIB のみ)

インポートライブラリの場合
対応する DLL を dumpbin /dependents mytest1.dll のように dumpbin に食わせる。
と MSVCR80D.DLL や MSVCM80D.DLL などの Visual C++ 系ライブラリが表示されるはず。
http://msdn.microsoft.com/ja-jp/library/abx4dbyh(v=vs.80).aspx
http://msdn.microsoft.com/ja-jp/library/abx4dbyh(v=vs.90).aspx
などを見ればいろいろ判別可能なはず。

純粋静的ライブラリは CRT やコンパイラに依存しないように作ることが可能なので
「こうすればいい」という一発回答は無いはずですよ。
引用返信 編集キー/
■64457 / inTopicNo.3)  Re[2]: libファイルがどのVS(.NET)で作成されたか知る方法
□投稿者/ howling (124回)-(2012/12/04(Tue) 12:43:13)
No64456 (774RR さん) に返信

ご返信頂きありがとうございます。

> 既にあるとおり CLI 配下の「あせんぶり」だと、原則 .LIB を使う必要は無いので

その通りですね。これについては迷いも無いので、DLLを参照で追加するのみです。

> .LIB の「作ったコンパイラ」バージョンなるものが必要になる、としたら
> - C++, C++/CLI などで作ったインポートライブラリ (対応する .DLL がある)
> - C++, C++/CLI などで作った純粋静的ライブラリ (.LIB のみ)

はい、今回はこちらのいずれかの場合に、例えばlibをD&Dすると一覧が作られて、
「作ったコンパイラ」バージョンを教えてくれるような物が無いかな?と思ったので質問しました。

> インポートライブラリの場合
> 対応する DLL を dumpbin /dependents mytest1.dll のように dumpbin に食わせる。
> と MSVCR80D.DLL や MSVCM80D.DLL などの Visual C++ 系ライブラリが表示されるはず。
> http://msdn.microsoft.com/ja-jp/library/abx4dbyh(v=vs.80).aspx
> http://msdn.microsoft.com/ja-jp/library/abx4dbyh(v=vs.90).aspx
> などを見ればいろいろ判別可能なはず。

なるほど…。
今回実は、きっと大丈夫だろうけどもう1度取ってくる(コンパイルし直す / DLし直す)作業を半日くらいかけてやりました。
結果、解決したわけですが、上にも書いたような物があれば楽だったのになぁと…。
そこまではいかないにしても、これで確認できるのは良いですね。試してみます。

> 純粋静的ライブラリは CRT やコンパイラに依存しないように作ることが可能なので
> 「こうすればいい」という一発回答は無いはずですよ。

これが可能なのかどうか?というのがちょっと謎だったりします。
今回出たXlen & Xranの外部参照エラーは前スレで調べた結果、
VS2008以前とVS2010以降が混在した場合に出る…ということだったのですが、
混在させてもこれを回避する方法はあるのでしょうか…?
また、MT系とMD系が混ざった場合にもエラーが出るはずです。
その時点で、依存しないように作ることは不可能なのでは…?
引用返信 編集キー/
■64487 / inTopicNo.4)  Re[3]: libファイルがどのVS(.NET)で作成されたか知る方法
□投稿者/ 774RR (28回)-(2012/12/05(Wed) 10:51:19)
ちょっと調べてみました。調査に使った環境は VS2005 です。
.LIB を生成するプロジェクト で簡単なソースを build した結果として:

結論:
Debug build した .obj ファイルには /DEFAULTLIB:"MSVCRTD" などの情報が埋め込まれる。
Release build した .obj ファイルには埋め込まれない。

実践:
dumpbin /all mylib.lib  (最終生成物)
dumpbin /all mylib1.obj (MYLIB.LIB を構成する要素の1つ)
のどちらとも、
・デバッグビルドなら DEFAULTLIB の補助情報を頼りにいろいろ区別できる。
・リリースビルドでは困難

まあ何にせよ一度 dumpbin に食わせて中を見てみるのはかなり有効です。

引用返信 編集キー/
■64488 / inTopicNo.5)  Re[4]: libファイルがどのVS(.NET)で作成されたか知る方法
□投稿者/ 774RR (29回)-(2012/12/05(Wed) 11:13:53)
> 今回出たXlen & Xranの外部参照エラーは前スレで調べた結果、
> VS2008以前とVS2010以降が混在した場合に出る…ということだったのですが、
> 混在させてもこれを回避する方法はあるのでしょうか…?

原因:
#include <string> などで標準テンプレートライブラリを使う場合であっても、
特定の型に特化した「事前にコンパイル済みのバイナリ」を使う実装が可能です。
template は指定された型や値に適合するクラスや関数や変数をコンパイル時に毎回作るのが
基本なので、上記のような使い方はかなりレアです(故意にそう作る必要があります)

VS2005 での Xran ほげほげ は、ヘッダファイル自体が事前にコンパイル済みバイナリを使うように
作られています (おそらく VS2008 でも実装は同じ:未確認です)
そしてコンパイラ付属のライブラリにコンパイル済みバイナリが入っています。
同一バージョンのコンパイラ+ライブラリを使う限りにおいてはこれで矛盾しません。

VS2010 では Xran ほげほげの詳細実装が変わったため、バイナリレベルでは非互換になっています。
VS2010 の付属ライブラリの中の Xran ほげほげ関数は
VS2008 の付属ライブラリの中の Xran ほげほげ関数とは
アセンブラレベルでの名称が異なっているため
・旧コンパイラでコンパイルしたユーザ作成バイナリと新コンパイラ付属のライブラリ または
・新コンパイラでコンパイルしたユーザ作成バイナリと旧コンパイラ付属のライブラリ
の組み合わせだとリンクに失敗してしまいます。

ユーザが使う public 関数レベルでの互換性は確保されているので、
最適解:「全ソースを新コンパイラでコンパイルしなおすべし」
次善策:「新コンパイラを使うのやめて旧コンパイラを使うべし」
ということになります。
Xran unresolved でぐぐってみると stackoverflow や msdn forum あたりの記事がバンバンヒットしますな。

で、コレを事前に知りたいのであれば、先のコメントのとおりで
dumpbin /all などに掛けて DEFAULTLIB コメントを探してみる (Release build では無理)
ということになりそうです。

回避策:としてもうひとつ考えられ
・旧(新)コンパイラ付属ライブラリから当該関数だけ抜き出してくる
それで期待通りに動くかどうかは試してみないとわかりません。

引用返信 編集キー/
■64489 / inTopicNo.6)  Re[5]: libファイルがどのVS(.NET)で作成されたか知る方法
□投稿者/ howling (128回)-(2012/12/05(Wed) 11:58:20)
No64488 (774RR さん) に返信

ご返信頂きありがとうございます。
今回色々と調べて頂き、大変感謝しております。

結果的に今回VS2010でVS2010以外でコンパイルされた物と予想される全てのライブラリをコンパイルし直したのですが、
これは正しかったようですね。良かった…。

さて、今回の問題は、この「予想」する方法についてだったのですが、
dumpbinで出力されたファイルを元に推測する形になるわけですか…。
この方法がある事が把握できただけでも助かりました。
ただ、コンパイルし直せる環境がある場合は、
コンパイルし直してしまった方が手っ取り早い場合がほとんどになりそうですね。

なんとなく、そういう一覧を出すツールとか無い物かと期待していたのですが、
回答を見ている感じ、そもそもそんな簡単な物では無いということが実感できました。

ただ、もし自分が作る側に回る場合には、互換性の問われないような、
できるだけそのライブラリの中だけで全ての実装を終える作りにしたいと思いました。
(サイズとかも考えないといけないですが)

今回大変勉強になりました。
774RRさん、(前スレから)とっちゃんさん、
ご回答頂きありがとうございました。

正確には問題自体は解決したわけはないですが、
充分な回答が得られたということで、解決済みにしたいと思います。

ありがとうございました。




解決済み
引用返信 編集キー/
■64491 / inTopicNo.7)  Re[6]: libファイルがどのVS(.NET)で作成されたか知る方法
□投稿者/ 774RR (30回)-(2012/12/05(Wed) 12:47:10)
ABI (Application Binary Interface) が同じならば
どのコンパイラでコンパイルしたオブジェクトであっても混在リンクでき、動作する
ってのが理想なわけですよ。その意味で
「オブジェクトファイルを作ったコンパイラ(やコンパイルオプション)を特定する」
ってのは無駄な作業である可能性があるわけです。
実際 Windows Platform でも Intel C Compiler と Microsoft C Compiler を混在させて
使うことは可能なわけですし。

コンパイラ自体がコンパイル結果のコメントレコードにいろいろ情報を埋め込んでいたり
しますし、そちらで探す方法もありますですが。

VS2005 の Release build した mylib1.obj を strings に食わせてみた
strings -a mylib1.obj | grep Microsoft
@ -compiler:"C:\Program Files\Microsoft Visual Studio 8\VC\bin\c2.dll"

某社の某組み込みマイコン用コンパイラでコンパイルした myobj.obj を同じく strings に食わせてみた
strings -a myobj.obj | grep ****
**** HogeHogeC:VerX.XX.YYY:CPU-Name

バイナリエディタで覗いてみたら -MT とかコンパイルオプションの簡単な一覧が c2.dll テキストの
直後に見つかったりとか・・・
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -