5

コンパイルオプションに応じて、多くのシンボルを定義する場合と定義しない場合がある、いくつかの静的ライブラリにリンクするプログラムがあります。OS X ではdlsym(3)、シンボル アドレスを取得するために NULL ハンドルを使用します。ただし、Linux ではdlsym(3)常に NULL を返します。

関数と変数を含む静的ライブラリにリンクし、それらのアドレスを出力しようとする単純なプログラム (以下のソース) を考えてみましょう。プログラムにシンボルが含まれていることを確認できます。

$ nm -C test | grep "test\(func\|var\)"
0000000000400715 T testFunc
0000000000601050 B testVar

ただし、プログラムを実行すると、どちらも見つけることができません。

$ ./test
testVar: (nil)
testFunc: (nil)

glibc の の実装を使用して、私たちがやろうとしていることは Linux で可能dlsym(3)ですか?

 メイクファイル

(スペースが空いてすみません)

LDFLAGS=-L.
LDLIBS=-Wl,--whole-archive -ltest -Wl,--no-whole-archive -ldl

libtest.o: libtest.c libtest.h
    libtest.a: libtest.o
test: test.o libtest.a
clean:
    -rm -f test test.o libtest.o libtest.a

libtest.h

#pragma once
extern void *testVar;
extern int testFunc(int);

libtest.c

#include "libtest.h"
void *testVar;
int testFunc(int x) { return x + 42; }

test.c

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char *argv[]) {
  void *handle = dlopen(NULL, 0);
  void *symbol = dlsym(handle, "testVar");
  printf("testVar: %p\n", symbol);
  symbol = dlsym(handle, "testFunc");
  printf("testFunc: %p\n", symbol);
  return 0;
}
4

1 に答える 1

4

プログラムを-rdynamic(またはld(1)--export-dynamicに対して)リンクする必要があります。

LDFLAGS += -rdynamic -L.

次に、すべてのシンボルがダイナミック シンボル テーブルに格納されます。dlsym

ところで、visibility属性は興味深いかもしれません。

于 2014-12-17T10:30:03.197 に答える