2

自分のアプリケーションからエクスポートされたシンボルを呼び出す必要があるため、「自分自身」でdlopen/を呼び出しても安全かどうかを知る必要がありLoadLibraryます。

例は次のとおりです。

LoadLibrary("test.exe");

と呼ばれるプログラムの内部test.exe

私はそれをテストし、動作しているように見えますが、実際にサポートされている動作であるかどうかはよくわかりません.

4

3 に答える 3

5

ここのMSDNドキュメントから...

システムは、ロードされたすべてのモジュールのプロセスごとの参照カウントを維持します。LoadLibraryを呼び出すと、参照カウントがインクリメントされます。FreeLibraryまたはFreeLibraryAndExitThread関数を呼び出すと、参照カウントが減少します。モジュールの参照カウントが 0 になるか、プロセスが終了すると (参照カウントに関係なく)、システムはモジュールをアンロードします。

上記のように、FreeLibraryを呼び出して自分でクリーンアップすることを忘れないでください。

代わりに本当に必要だったのはGetModuleHandleです。

指定されたモジュールのモジュール ハンドルを取得します。モジュールは、呼び出しプロセスによってロードされている必要があります。

実際、あなたがやろうとしていることは特殊なケースですらあります。

lpModuleName [入力、オプション]

...

このパラメーターが NULL の場合、GetModuleHandleは、呼び出しプロセスの作成に使用されるファイル (.exe ファイル) へのハンドルを返します。

それで、これを試して...

#include <stdio.h>
#include <windows.h>

__declspec(dllexport) void print(void) {
  puts("OK");
}

main() {
  HMODULE mod = GetModuleHandle(0);
  FARPROC proc = GetProcAddress(mod, "print");
  proc();
  return 0;
}

...動作するようです:

C:\dev\scrap>gcc -oprint print.c

C:\dev\scrap>print
OK

dlopenの場合、非常によく似ています。

filenameが NULL ポインタの場合、返されるハンドルはメイン プログラム用です。このハンドルをdlsym () に指定すると、メイン プログラムでシンボルが検索され、続いてプログラムの起動時に読み込まれたすべての共有ライブラリが検索され、次にフラグRTLD_GLOBALでdlopen () によって読み込まれたすべての共有ライブラリが検索されます。

于 2012-07-31T15:43:44.697 に答える
2

これは簡単に行うことができます-GNUdlopen()拡張機能として指定された疑似ハンドルがありRTLD_DEFAULTます。これは自分自身のハンドルのように機能するため、呼び出しをスキップして次のdlopen()ように記述できます。

dlsym(RTLD_DEFAULT, "entry_func");

例えば:

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

void print(void) {
  puts("OK");
}

int main() {
  void (*proc)(void) = dlsym(RTLD_DEFAULT, "print");
  assert(proc);
  proc();
  return 0;
}

これを機能させるには、でコンパイルする必要があることに注意してください-rdynamic

最近のSolarisマシンのマンページによると、RTLD_DEFAULTそこにもあります。

于 2012-07-31T15:56:37.723 に答える
2

Windows での簡単なテスト:

#include <windows.h>
#include <stdio.h>

__declspec(dllexport) FARPROC Test() { 
    printf("It worked");
}

int main(int argc, char **argv) {
    HMODULE m = LoadLibrary(argv[0]);
    FARPROC test = GetProcAddress(m, "Test");
    test();
    return 0;
}

次の出力が生成されました。

It worked

理論的には、他のバージョンの Windows で壊れないことを保証するものではないと思いますが、それはかなり疑わしいと思います。

于 2012-07-31T14:05:09.840 に答える