8

Windows では、いくつかの引数が DllMain コンストラクターに渡されます。

BOOL WINAPI DllMain(  
  __in  HINSTANCE hinstDLL,  
  __in  DWORD fdwReason,  
  __in  LPVOID lpvReserved  
);

hinstDLL から、GetModuleFileName() を使用して DLL 自体の完全修飾ファイル名を取得できます。

LPTSTR str = new TCHAR[256];  
int libNameLength = GetModuleFileName(hinstDLL, str, 256);  
delete[] str;  

上記の例では、str には、C:\Windows\System32\MyFile.dll のように、ロードされたばかりの DLL の完全な名前が含まれています。

Linux では、共有オブジェクト コンストラクターに引数は渡されません。

void `__attribute__` ((constructor)) on_load(void);

この場合、DLL の完全な名前を取得するにはどうすればよいですか? ソリューションが Mac でも動作する場合は、追加のクレジットが必要です。:-)

4

2 に答える 2

4

関数はあなたが望むことをするかもしれないと思いdladdrます。マニュアルページから:

関数 dladdr() は、関数ポインターを取り、それが配置されている名前とファイルを解決しようとします。情報は次の Dl_info構造体に格納されます。

typedef struct {
    const char *dli_fname;  /* Pathname of shared object that
                               contains address */
    void       *dli_fbase;  /* Address at which shared object
                               is loaded */
    const char *dli_sname;  /* Name of nearest symbol with address
                               lower than addr */
    void       *dli_saddr;  /* Exact address of symbol named
                               in dli_sname */
} Dl_info;

addr に一致するシンボルが見つからない場合、dli_snamedli_saddrは に設定されNULLます。

dladdr()エラーの場合は 0 を返し、成功の場合はゼロ以外を返します。

したがって、関数ポインター (コンストラクター自体のアドレスなど) を指定するだけで、ファイル名とその他の情報が得られます。サンプルコードは次のとおりです。

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

__attribute__((constructor))
void on_load(void) {
    Dl_info dl_info;
    dladdr(on_load, &dl_info);
    fprintf(stderr, "module %s loaded\n", dl_info.dli_fname);
}

編集: この関数は OS X でも同じセマンティクスで存在するようです。

于 2009-10-29T23:35:12.823 に答える
1

これを行うための非常に醜く恐ろしい方法の1つは、/ proc / pid / mapsを調べて、on_load実行されている関数のアドレスを含むマッピングを探すことです。

于 2009-10-29T08:43:12.030 に答える