4

ライブラリを動的にロードするアプリケーションがあり、ライブラリを動的にロードします...

Windowsでは、ロードされたすべてのモジュールを繰り返し処理して、関心のあるシンボルを探すことができます。Unix/Linux環境でそれを行う方法がわかりません。最初の2つのシンボルを使用するdlsym(dlopen(0, flag))dlsym(RTLD_DEFAULT / RTLD_NEXT)、検索するモジュールの順序を知っています。どのようにして、より深く、特定のシンボルのすべての定義を取得できますか?

4

2 に答える 2

6

シャード オブジェクト内のシンボルを見つけるには、 で開きますdlopen

 void* foobar = dlopen ("/usr/local/lib/foobar.so", RTLD_NOW);
 void* mysymbol = dlsym (foobar, "mysymbol");

更新これは、「foo」という名前のすべてのシンボルを反復処理するプログラムです。これは POSIX ではなく、GNU ライブラリです。POSIX がそのような機能を提供していないことはほぼ確実です。

#define _GNU_SOURCE 
#include <link.h>
#include <dlfcn.h>
#include <stdio.h>

void doit (const char* s)
{
    void* obj = dlopen (s, RTLD_LAZY);
    void* fcn = dlsym (obj, "foo");
    if (fcn)
        printf ("Object %s has 'foo' at addr %p\n", *s ? s : "(exe)", fcn);
}    
int cb (struct dl_phdr_info *info, size_t size, void *data)
{
    doit (info->dlpi_name);
    return 0;
}    
int main ()
{
    dl_iterate_phdr (cb, 0);    
    return 0;
}

出力は次のとおりです。

Object (exe) has 'foo' at addr 0xb76f8418
Object (exe) has 'foo' at addr 0xb76f8418
Object /tmp/libfoo.so has 'foo' at addr 0xb76f8418
Object /tmp/libfoo1.so has 'foo' at addr 0xb76f5418
Object /tmp/libfoo2.so has 'foo' at addr 0xb76f2418

いくつかの重複がありますが、これは小さな問題です。

于 2011-11-30T17:26:07.527 に答える
2

解決策を探している人々の生活を楽にするために、自分自身の質問に答えること。統一された方法はありません。ロードされたモジュールを繰り返し処理したい場合は、次のコマンド/データ型を検索する必要があります (専門家はそれについてコメントするよう招待されています)。

Windows:
MODULEENTRY32、CreateToolhelp32Snapshot、Module32First、Module32Next

Linux:
nm の回答で説明されているように、適切なモジュールが見つかったときにコールバックからゼロ以外を返します (ループを終了します)。

AIX:
loadquery(L_GETINFO, buffer, size), struct ld_info.

HP-UX:
dlget、dlgetname (モジュール パスが必要な場合)。

Solaris:
ldinfo、Link_map。

さらに、モジュールを dlopen し、新しいハンドルからシンボルを取得して、ライブラリの参照カウントを増やし、アンロードされないようにすることをお勧めします。少なくとも AIX では、ライブラリがロードされて再度初期化されるという副作用が生じる可能性がありますが、ほとんどの場合、アンロードされたライブラリから関数を呼び出そうとするよりはましです。

于 2011-12-05T00:07:36.943 に答える