[Uneex] libdl,dlopen и т.д.
Nikita V. Youshchenko
uneex@cs.msu.su
Sat, 3 Nov 2001 23:56:48 +0300
> 1. B /usr/include/dlfcn.h комментарии более, чем краткие, поэтому
> назначение ключей RTLD_xxx неясно. Не знает ли кто нибудь про них
> поподробнее ?
man dlopen - там все написано (только что проверил лично)
> 2. Как заставить ее (dlopen + dlsym) "вытащить" адрес функции из
> программы, в которой dlsym вызывается. Т.е. вызвать мою функцию
> по ее имени. Какие для этого нужны ключи компилятора и dlopen?
Это весьма системно зависимо.
На моей машине (Debian unstable, glibc 2.2.4, gcc 2.95.4) не сработало.
Однако, проблема элементарно обходится. Достаточно представить всю
программу не как ELF executable, а как ELF shared library. Т.е. линковать
командой
gcc -shared -o x.so $(SOURCES)
После чего ввести
gcc -o x x.so
в результате чего будет создан исполняемый файл x, который использует все
(включая main) из x.so. Теперь при помощи dlopen ( "x.so", RTLD_LAZY )
можно получить доступ до всех функций.
nikita@sercond:/tmp/x> cat x.c
#include <dlfcn.h>
#include <stdio.h>
void func ( void )
{
printf ( "func() called\n" );
}
int main()
{
void * h = dlopen ( "/tmp/x/x.so", RTLD_LAZY );
void (*f)() = dlsym ( h, "func" );
(*f)();
}
nikita@sercond:/tmp/x> gcc -shared -o x.so x.c -ldl
nikita@sercond:/tmp/x> gcc -o x x.so
nikita@sercond:/tmp/x> LD_LIBRARY_PATH=`pwd` ./x
func() called
nikita@sercond:/tmp/x>
В этом примере надо задать LD_LIBRARY_PATH, чтобы x.so был найден.
Чтобы этого избежать, можно прописать путь прямо в исполняемый файл x:
nikita@sercond:/tmp/x> gcc -o x x.so -Wl,-rpath,`pwd`
nikita@sercond:/tmp/x> ./x
func() called
nikita@sercond:/tmp/x>
Никита