[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>

Никита