0

このOSXコード(議論を容易にするためにゴルフをしています)をUbuntu Linuxで動作させようとしています。

cat >main.c <<EOF
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void provided_by_main() { puts("Hello main!"); }
int main() {
  void *provider_so, *needer_so;
  (provider_so = dlopen("provider.so", RTLD_NOW)) || printf("Fail %s\n", dlerror()) && (exit(0),0);
  (needer_so = dlopen("needer.so", RTLD_NOW)) || printf("Fail %s\n", dlerror()) && (exit(0),0);
  void (*needer)() = dlsym(needer_so, "needer");
  needer();
}
EOF

cat >needer.c <<EOF
extern void provider();
void needer() { provider(); }
EOF

cat >provider.c <<EOF
#include <stdio.h>
void provider() { puts("Hello provider!"); }
EOF

gcc -shared -o provider.so provider.c
gcc -shared -o needer.so needer.c -dynamic -undefined dynamic_lookup
gcc -o main main.c -ldl
./main
Hello provider!

Linux では、試行錯誤と StackOverflow を介して、がリンクされていない限りneeder、 で定義されているものを参照できないと判断しました。mainmain-rdynamic

gcc -shared -fpic -o provider.so provider.c
gcc -shared -fpic -o needer.so needer.c -Dprovider=provided_by_main
gcc -o main main.c -ldl -rdynamic
./main
Hello main!

ただし、 「チェーン」全体が次のようにコンパイルされていても、needer提供されるものを見ることはできません。provider-rdynamic

gcc -shared -fpic -o provider.so provider.c -rdynamic
gcc -shared -fpic -o needer.so needer.c
gcc -o main main.c -ldl -rdynamic
./main
Fail needer.so: undefined symbol: provider

それで、どうすればこれを機能させることができますか?

または、Linux では設計上不可能である場合、なぜ不可能なように設計されているのでしょうか?

(OSX と同等: OS X 上の C で dlopen() された動的ライブラリからメイン プログラムのグローバル変数にアクセスする)

実際の複雑な問題:私の実際のプログラムでprovider.soは、実行時にコードが生成され、シンボルの名前はリンクさproviderれるまで決定されません。mainただし、修正を伴う回答であってもmain.c、正しい方向への一歩となります。

4

2 に答える 2

1

これが OS X では機能し、Linux では失敗する理由は、前者では RTLD_GLOBAL が dlopen のデフォルトのシンボル可視性であるのに対し、後者ではデフォルトで RTLD_LOCAL が設定されるためです。使用 (慎重に):

dlopen("provider.so", RTLD_NOW | RTLD_GLOBAL);

一方、 -rdynamic は、実行可能ファイルで定義されている不足しているライブラリ シンボルにのみ適用されますが、他の場所には適用されません。


sed -i 's/RTLD_NOW/RTLD_NOW|RTLD_GLOBAL/' main.c
gcc -shared -fpic -o provider.so provider.c
gcc -shared -fpic -o needer.so needer.c
gcc -o main main.c -ldl
./main
Hello provider!
于 2013-08-03T00:52:48.483 に答える