アプリ版:「スタンプのみでお礼する」機能のリリースについて

スタティックリンクライブラリで2重リンクをしようとすると、warning LNK4006が発生してしまいます。

メッセージ:
"~で定義されています; 2 つ目以降の定義は無視されます"

例えば、
aaa.libがbbb.libとccc.libをリンクしてて、bbb.libとccc.libはそれぞれddd.libをリンクしているとします。*.libはすべてスタティックリンクライブラリで提供を考えています。

  [ aaa.lib ]
   |   |
[bbb.lib] [ccc.lib]
  |     |
[ddd.lib] [ddd.lib]


調べてみると「ライブラリーを結合する時に,このエラー・メッセージが表示された場合,ライブラリーに既に存在しているシンボルを追加しようとしています。」ということで、要は"ddd.lib"が重複してリンクされているという事のようなのですが、原因ばかりで解決策が分かりません。

LNK4006の解決法が分かれば良いのですが、最終的にはこの構成で"aaa.lib"だけで提供するようなライブラリを作成したいです。実現するためにはどのようにしたら良いのでしょうか?アイデアを頂けたら助かります。また詳しい方がいらっしゃいましたらご教授お願いいたします!

※Windows2000でVisualStadio.NET2003を使用してます。

A 回答 (4件)

> でもスタティックだとそうしなくとも良いのですね。



DLLというのはある種完結してますので、ビルド時に不明なシンボルがあるとエラーになります。

一方、スタティックなライブラリはただのobjファイルのアーカイブです。
不明なシンボルがあっても関知せずにビルド成功します。
実際にそのライブラリをリンクして実行ファイルを作る際に、初めてシンボルが解決できればよいのです。

で、以下は状況が断定しかねるの憶測交じりになりますが、かなりDLLの感覚に引っ張られていませんか。

もしかして、bbb.libやccc.libにそれぞれddd.libを指定していませんか。
最終的にaaa.libひとつで公開したいのならそのリンクは不要というか余計です。はずしてください。

スタティックライブラリ内の.objは、VC付属のlib.exe(ライブラリアン)等で確認できまます。
一覧表示などしてみてください。

言ってしまえば今回の場合、これを確認しながら、最終的にすべての.objがひとつだけリンクされるように
各ライブラリを組み合わせてあげれば、aaa.libの完成です。

スタティックリンクする場合、中間のライブラリには依存するライブラリをリンクする必要がありません。
「静的にリンクする」ということはそのライブラリ内のobjを取り込んでしまうということです。
bbb.libやccc.libにddd.libを静的リンクしてしまうと、それぞれにddd.lib内の.objが含まれてしまいますので、
aaa.lib作成の際にそれらが警告を出すでしょう。

普通、スタティックなライブラリ同士をリンクすることも稀だと思います。
# 今回のように、配布用などにまとめたいときくらい?

aaa.libだけを公開したいのであれば、bbb.libやccc.libにddd.libをリンクする必要はありません。
(DLLのように依存関係のライブラリをリンクする意味はありません)
ということで、bbb.lib、ccc.lib、ddd.libを個別に作成し、aaa.libに直接、ひとつずつリンクしてください。
    • good
    • 0
この回答へのお礼

ありがとうございます。かなり参考になりました。
かなりDLLの感覚に引っ張られていました。
最終的に.obj1つずつまとめた塊と思えば、かなり頭で整理できました。

妙だったのが、VC7.0でビルドの順番を変えたいがために、依存関係を指定していたのですが、そうするとLNK4006のエラーが出ていたことです。
普通にひとつずつビルドしていくと通るので、依存関係を指定することでリンクして取り込もうとするんでしょうかね??

とりあえず解決したようです。ありがとうございました。

お礼日時:2006/08/04 00:34

bbb.libやccc.libに直接ddd.libをリンクせず、


必要に応じてbbb.libとddd.libをリンクするのが定石かと。
# この時点で個別リンクする利点/意味ってないような。

最終的に、aaa.libだけを提供したいということなので、
・bbb.libやccc.libではddd.libをリンクしない
・aaa.libを作成する際にbbb.lib,ccc.lib,ddd.libをリンクしてaaa.libを作成する。
とするのがよさそうです。

この回答への補足

さらに回答ありがとうございます。
もともとDDLで作成してて、スタティックにしようとしたところ、こういう構成になりました。

というのも、bbb.libもccc.libもddd.libをリンクしないと動作しなかったためです。
でもスタティックだとそうしなくとも良いのですね。

早速試してみました。するとちょっと妙な感じなんですが・・・。
bbb.libで使用してるddd.libの関数と、ccc.libで使用しているddd.libがaaa.libでリンクするときに同様のwarningが発生します。

また、aaa.libで依存ファイルの設定にddd.libを設定しなくともリンクできているようです。
コードから自動的にリンクする機能がデフォルトであるとか??

補足日時:2006/08/02 23:07
    • good
    • 0

あ、ddd.libが同一でも、


ddd.libでグローバル変数を互いに操作している場合、
予期しない衝突の可能性もあります。ご注意を。
    • good
    • 0

その警告は、「同じものが重複していたので、最初の物を使った」という通知です。


(順番はリンカへの指定による)

二つのddd.libがまったく同一のものなら、
最初の方が使われただけのことなので無視してかまいません。

もしも、ふたつのddd.libが別物で互換性がないならば、
後の方のddd.libを使おうと思っていたライブラリ(bbb or ccc)は、
予期せぬライブラリの関数を呼び出しますから、おかしくなる可能性が高いです。
# これを予防するための警告です。
この場合、ddd.libを同じものにして作り直さない限り、スタティックリンクライブラリはうまく動きません。
作り直すか、DLLを検討することになります。
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。
ddd.libは同じもので作っています。
それでも警告は出てしまうんですね。

警告の数がものすごいことになっているのですが、警告自体を消すことは可能でしょうか??

お礼日時:2006/08/02 01:06

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!