一般的に言えば、弱い実装を に入れなければmain
、リンカーは実行時に最終的に解決します。しかし、これを に実装すると、このスタティックをリンクするときにmain.c
強い境界 ( ) でのみオーバーライドできます。bar.c
http://www.bottomupcs.com/libraries_and_the_linker.htmlを読んでください- このトピックに関する興味深いものがたくさん含まれています。
私は自分でテストを行いました:
bar.c
#include <stdio.h>
void bar()
{
puts("bar.c: i'm the strong bar()");
}
baz.c
#include <stdio.h>
void __attribute__((weak)) bar()
{
puts("baz.c: i'm the weak bar()");
}
main.c
#include <stdio.h>
#ifdef V2
void __attribute__((weak)) bar()
{
puts("main: i'm the build in weak bar()");
}
#else
void __attribute__((weak)) bar();
#endif
int main()
{
bar();
return 0;
}
私のメイクファイル:
all:
gcc -c -o bar.o bar.c
gcc -shared -fPIC -o libbar.so bar.o
gcc -c -o baz.o baz.c
gcc -shared -fPIC -o libbaz.so baz.o
gcc -o main1 main.c -L. -lbar -lbaz
gcc -o main2 main.c -L. -lbaz -lbar
LD_LIBRARY_PATH=. ./main1 # => bar.c
LD_LIBRARY_PATH=. ./main2 # => baz.c
LD_LIBRARY_PATH=. LD_PRELOAD=libbaz.so ./main1 # => baz.c (!!)
LD_LIBRARY_PATH=. LD_PRELOAD=libbaz.so ./main2 # => baz.c
gcc -o main3 main.c bar.o baz.o
gcc -o main4 main.c baz.o bar.o
./main3 # => bar.c
./main4 # => bar.c
gcc -DV2 -o main5 main.c -L. -lbar -lbaz
gcc -DV2 -o main6 main.c -L. -lbaz -lbar
LD_LIBRARY_PATH=. ./main5 # => main's implementation
LD_LIBRARY_PATH=. ./main6 # => main's implementation
gcc -DV2 -o main7 main.c -L. -lbar -lbaz
gcc -DV2 -o main8 main.c -L. -lbaz -lbar
LD_LIBRARY_PATH=. LD_PRELOAD=libbaz.so ./main7 # => main's implementation
LD_LIBRARY_PATH=. LD_PRELOAD=libbaz.so ./main8 # => main's implementation
gcc -DV2 -o main9 main.c -L. -lbar -lbaz
gcc -DV2 -o main10 main.c -L. -lbaz -lbar
LD_LIBRARY_PATH=. LD_PRELOAD=libbar.so ./main9 # => main's implementation
LD_LIBRARY_PATH=. LD_PRELOAD=libbar.so ./main10 # => main's implementation
gcc -c bar.c
gcc -c baz.c
gcc -o main11 main.c bar.o baz.o
gcc -o main12 main.c baz.o bar.o
./main11 # => bar.c
./main12 # => bar.c
gcc -o main13 -DV2 main.c bar.o baz.o
gcc -o main14 -DV2 main.c baz.o bar.o
./main13 # => bar.c
./main14 # => bar.c
main1 && main2 を見てください... 弱い実装を入れずに、弱い実装をmain.c
ライブラリに保持し、強い実装を別のライブラリに保持すると、弱い実装を上書きすることができます。 lib は の強力な実装を定義しますbar()
。