Спасибо за все ответы.У меня есть решение, которое, кажется, работает.Вот проблема подробно с примером.
В main.c у нас есть:
#include <stdio.h>
extern int foo();
int bar()
{
printf("bar in main.c called\n");
return 0;
}
int main()
{
printf("result from foo is %d\n", foo());
printf("result from bar is %d\n", bar());
}
В foo.c у нас есть:
extern int bar();
int foo()
{
int x = bar();
return x;
}
В баре.c имеем:
#include <stdio.h>
int bar()
{
printf("bar in bar.c called\n");
return 2;
}
Скомпилируйте bar.c и foo.c:
$ gcc -fPIC -c bar.c
$ gcc -fPIC -c foo.c
Добавьте bar.o в статическую библиотеку:
$ ar r libbar.a bar.o
Сейчассоздать общую библиотеку, используя foo.o, и связать со статическим libbar.a
$ gcc -shared -o libfoo.so foo.o -L. -lbar
Скомпилировать main.c и связать с общей библиотекой libfoo.so
$ gcc -o main main.c -L. -lfoo
Установить LD_LIBRARY_PATH для поиска libfoo.so и запустите main:
$ setenv LD_LIBRARY_PATH `pwd`
$ ./main
bar in main.c called
result from foo is 0
bar in main.c called
result from bar is 0
Обратите внимание, что вызывается версия bar в main.c, а не версия, связанная с общей библиотекой.
В main2.c мы имеем:
#include <stdio.h>
#include <dlfcn.h>
int bar()
{
printf("bar in main2.c called\n");
return 0;
}
int main()
{
int x;
int (*foo)();
void *handle = dlopen("libfoo.so", RTLD_GLOBAL|RTLD_LAZY);
foo = dlsym(handle, "foo");
printf("result from foo is %d\n", foo());
printf("result from bar is %d\n", bar());
}
Скомпилируйте и запустите main2.c (обратите внимание, нам не нужно явно ссылаться на libfoo.so):
$ gcc -o main2 main2.c -ldl
$ ./main2
bar in bar.c called
result from foo is 2
bar in main2.c called
result from bar is 0
Теперь foo на панели вызовов общей библиотеки в общей библиотекеи панель основных вызовов в файле main.c
Я не думаю, что это поведение интуитивно понятно, и использование dlopen / dlsym требует больших усилий, но это действительно решает мою проблему.
Еще раз спасибо засomments.