3

WindowsおよびLinuxでは、GetProcAddress()またはdlsym()のいずれかを使用して、ダイナミックライブラリから使用する関数ポインターが設定された構造体を返すことは問題なく機能するようです。

...しかし、この比較的単純なアプローチがうまく機能しているように見えるときに、void *ポインターを関数ポインターにキャストしたり、dlfuncの使用について話したりすることについて、質問をしたり不平を言ったりする人は非常に多いようです。

それで、あなたがこれをしたくない特別な理由はありますか?

このようなコードは、何らかの理由で移植性がありませんか?

このアプローチは、明示的に名前が付けられた関数とバインドされた関数を共有する場合にのみ機能することを理解していますが、私に関する限り、プラグインをロードする場合は問題ありません...?

header.h:

/* C++ safety & windows support */
#ifdef __cplusplus
  #if _WIN32 || _WIN64
    #define __EXT extern "C" __declspec(dllexport)
  #else
    #define __EXT extern "C"
  #endif
#else
  #if _WIN32 || _WIN64
    #define __EXT __declspec(dllexport)
  #else
    #define __EXT extern
  #endif
#endif

struct a_sym_table {
  int (* action) (int argc, char *argv[]);
};

__EXT struct a_sym_table liba_symbols;

source.c:

int perform_action_lib_a(int argc, char *argv[]) {
  int rtn = perform_action_lib_b() + perform_action_lib_c();
  return(rtn);
}

struct a_sym_table liba_symbols = {
  &perform_action_lib_a
};

編集:わかりやすくするために、シンボルをロードするコードはプラットフォームによって異なりますが、このアプローチにより、共有ライブラリを変更せずにさまざまなプラットフォームに移植できます。

それは私が尋ねるときに私が話していることです、あなたがこれをしない理由はありますか?

私が知りたいのは、移植性のためにこのような共有ライブラリを構築しない正当な理由があるかどうかです。

4

1 に答える 1

3

共有ライブラリのデータにアクセスしています。これがdlsym()の目的です。ダイナミックリンカは、ライブラリの境界を通過する関数ポインタを適切に処理できる必要があります。少なくともUNIXライクなシステムでは。Windowsについてはわかりませんが、ある種のポインターが機能し、他の種類のポインターが機能しなかった場合、多くのことが壊れることを想像できます。

移植性に関しては、「#if _WIN32 || _WIN64」の背後にすでにあるものを持っているか、dlsymを実装しているシステムにすでに制限されています。これは、あなたがしていることが、いくつかの厳密な標準文書に従わずにテストすることによって機能するようになったことをすでに示唆しているはずです。したがって、「これが機能するものは何でも」に移植できます。

于 2012-11-14T10:53:40.843 に答える