弱いリンクとリンク期間エラー


以前、アプリケーション開発者にMCUおよびその周辺機器のライブラリを提供するSDKを作ったことがあります.割り込み部分の文法はあまり見られないし、割り込み番号の管理も複雑なので、app担当者は割り込み処理で自分が関心を持っているコードを書けばいい道を提供したいと思っています.
当時思いついたのはコールバック関数の登録です.ちょっと面倒ですが、コールバック関数のタイプを宣言します.コールバック関数ポインタを判断する.今やっともっと簡単な方法を見ました:弱いリンク.
リンクを参照:http://blog.sina.com.cn/s/blog_a9303fd90101d5su.html
以下は貼り付け内容です.
__attribute__ のweak,alias属性 .
 (2013-03-13 16:15:43)
ラベル: it
分類: Linux
Weak AliasはWeak Referenceとは全く関係ありませんが、Weak Referenceを見たときに思いついただけです.
Weak Aliasはgcc拡張の中のもので、実際には関数の属性です.これはライブラリの実装でよく使われるかもしれません.例えばglibcではたくさん使われています.1段書き写す. gccマニュアルでは関数属性が何をしているのかを説明していますが、
In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.
まずコードをつけて、weak aliasがどのように書くかを見てみましょう.最初のファイルdummy.cの内容は、
#include int __foo() { puts(”I do no thing.”); } int foo() __attribute__ ((weak, alias(”__foo”)));

Weakとaliasはそれぞれ2つの属性である.Weak使  foo  この記号はglobal symbolではなく、ターゲットファイルでweak symbolとして使用されます.使用する  nm  コマンドはdummy.cをコンパイルして生成したターゲットファイルを表示します. fooはweak symbolで、その前のマークはWです.関数にweakプロパティを付けると、関数が定義されていなくても、関数が呼び出されてコンパイルに成功します.
00000000 T __foo 00000000 W foo U puts

aliasは  foo  はい  __foo  の別名、_fooとfooは同じコンパイルユニットで定義する必要があります.そうしないとコンパイルエラーが発生します.
では、これの使い道は?
2番目のファイルを見てfunc.c、
#include int foo() { puts(”I do something.”); }

ここに関数の名前があります.  foo .func.cとdummy.cをコンパイルして2つのターゲットファイルを得た場合、func.oとdummy.oを同時に使用して他のターゲットファイルとリンクすると、他のターゲットファイルに記号が参照されます.  foo、最終的にはfunc.cで定義された関数を使用します.  __foo別名がありますが  foo .つまり、私たちが最終的に使用する関数は「実際に仕事をする」関数です.もちろん、dummy.oリンクを単独で使う場合はその「仕事をしない」関数を使います.dummy.oの  foo  Weak symbolでないと、リンク時に競合します.これがweakを使用する理由です.
glibcの実装ではweak aliasがよく使われています.例えば  socket  関数は、Cファイルに1つ表示されます.  __socket  関数は、ほとんど何もしていません.エラーコードを設定して、何かを返しているだけです.同じCファイルに__socketを追加します のweak alias別名  socket .実際に作業を完了したコードはアセンブリで実現され、別のアセンブリファイルにはシステム呼び出し番号が設定され、実行されます.  sysenter  または  int  などの動作でシステム呼び出しを要求します.以前glibcの中のシステム呼び出しの実現を見たとき、うっとうしくて長い間、weak aliasというものを知ったのです.
-----------------------------------------------------------------------------------------
弱いリンクを使用すると、リンク競合が発生するという問題が発生します.
http://blog.csdn.net/liucanrui/article/details/6453986
VCコンパイルエラー:uafxcw.lib(afxmem.obj):error LNK 2005:“void*_cdecl operator new(unsigned int)”(?2@YAPAXI@Z)は既にLIBCMT.lib(new.obj)で定義されている
コンパイルエラー 2010-03-30 21:47:54 1801を読む コメント0  サイズ:大中小 購読する
1>uafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)"(??2@YAPAXI@Z)は既にLIBCMT.lib(new.obj)で1>uafxcw.lib(afxmem.obj):error LNK 2005:"void__cdecloperator delete(void*)"(?3@YAXPAX@Z)LIBCMT.lib(delete.obj)で定義されている1>uafxcw.lib(afxmem.obj):error LNK 2005:"void*_cdecl operator new[](unsigned int)"(??_U@YAPAXI@Z)LIBCMT.lib(new 2.obj)で1>../bin/TLLogger_が定義されていますUnicode_Release.exe:fatal error LNK 1169:1つ以上の多重定義記号を見つけます
 
解決方法:
http://blog.vckbase.com/zaboli/archive/2010/02/05/40921.aspx
理由:CRTライブラリはnew、delete、DllMain関数に弱い外部リンクを使用します.MFCライブラリにはnew、delete、DllMain関数も含まれています.これらの関数はMFCライブラリをリンクしてからCRTライブラリをリンクする必要があります.C実行時(CRT)ライブラリとMicrosoftベースクラス(MFC)ライブラリのリンク順序が間違っている場合、以下のLNK 2005エラーが発生する可能性があります.解決方法:リンクを正しい順序でライブラリにリンクするように強制します.Project->properties->Linker->Ignore Specific Library uafxcwd.lib Libcmtd.libを追加 (入力-特定のライブラリを無視)Additional Dependenciedにuafxcwd.lib Libcmtd.libを追加(入力-追加オプション)
------------------------------------------------------------------------------------------