この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
、 で定義されているものを参照できないと判断しました。main
main
-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
、正しい方向への一歩となります。