をLinuxへWindowsプロジェクトを移植するには、一つだけがプロセスのすべてのコンポーネントによって使用され、実行時に、しかしAのコピーが含まれます。
// h.h
extern int a;
void b(void);
void c(void);
// a.c
#include "h.h"
int a = 0;
// b.c
#include <stdio.h>
#include "h.h"
void b(void)
{
printf("%i\n", a++);
}
// c.c
#include <stdio.h>
#include "h.h"
void c(void)
{
printf("%i\n", a++);
}
//main.c
#include <stdio.h>
#include "h.h"
int main()
{
b();
c();
}
#Makefile
main: libxc.so libxb.so
cc -o main main.c -L. -lxc -lxb
libxb.so:
cc -fPIC -shared a.c b.c -o libxb.so
libxc.so:
cc -fPIC -shared a.c c.c -o libxc.so
$make
$ LD_LIBRARY_PATH=. ./main
0
1
libxa.so
から
シンボルテーブル:
53: 000000000020098c 4 OBJECT GLOBAL DEFAULT 24 a
libxc.so
より:
53: 000000000020098c 4 OBJECT GLOBAL DEFAULT 24 a
デフォルトの可視性は、STV_DEFAULT
あるLSBに従って:
STV_DEFAULT
0:シンボルの結合タイプで指定されSTV_DEFAULT
属性を持つシンボルの可視性があります。つまり、 グローバルシンボルとウィークシンボルは、 のコンポーネント(実行可能ファイルまたは共有オブジェクト)を定義している外で表示されます。以下で説明するように、ローカルシンボルは です。グローバルシンボルおよびウィークシンボルも プリエンプティブです。つまり、別のコンポーネントの同じ という名前の定義によって先取りされる可能性があります。
man 5 elf
:
STV_DEFAULT
:デフォルトシンボルの可視性ルール。 他の モジュールでは、グローブと弱いシンボルを使用できます。ローカルモジュール内の参照は、他の モジュール内の定義によって挿入されてもよい( )。 SysV ABIについて
:
シンボリック参照を解決する、 ダイナミックリンカは幅優先探索とシンボルテーブルを調べます。 つまり、実行可能な プログラム自体のシンボルテーブルを参照してから、 DT_NEEDED
エントリのシンボルテーブル(順番に)、次に2番目のレベルDT_ NEEDED
エントリなどのシンボルテーブルを参照します。
シンボルにSTV_HIDDEN
を使用すると、そのシンボルが共有オブジェクトの外側に表示されないようになります。
対照的に、Windowsでは、シンボルは常に特定のDLLからインポートされ、シンボルはデフォルトで他のDLLにエクスポートされません。
答えが得られない場合は、グローバル変数を1ライブラリから変更し、2番目のライブラリからその値を確認することで、簡単なテストを行うことができます。 –