7

言い直された質問(すでに解決されていますが):

Linux で共有オブジェクト ライブラリをロードするために dlopen(3) を使用する際に問題が発生しました。このライブラリは、私が構築したライブラリのシステムの一部であり、実行時に中央の実行可能ファイルによってすべてロードされます。このすべては、Code::Blocks の単一のワークスペースに編成されます。各プロジェクトには、プログラムに同梱される Source と呼ばれるディレクトリ内の独自のフォルダーが与えられます。実行可能ファイルのビルド ディレクトリは、実行可能ファイルとソース フォルダーが同じディレクトリにあるように、独自のソース コードから 2 つ後ろのディレクトリです。ライブラリも実行可能ファイルと同じディレクトリにビルドされるので、当然ライブラリの名前を渡します私は示されているように開こうとしています:

int main(int argc, char** argv) {
    void* hLibrary = dlopen("libLibrary.so", RTLD_NOW | RTLD_GLOBAL);
    if(hLibrary == NULL) {
        fprintf(stderr, "%s\n", dlerror());
        return 1;
    }

    return 0;
}

これは、ソース コードのディレクトリを上記の配置に変更するまで、ビルド ディレクトリがソース コードと同じだったある時点で機能していました。この時点での問題は、ファイルが明らかに存在し、実行可能ファイルと同じディレクトリにあるにもかかわらず、dlerror() が「libLibrary.so を開けません: そのようなファイルまたはディレクトリはありません」を返すことです。次に、代わりに「/libLibrary.so」を渡そうとしました。これは、dlopen(3) のマニュアル ページによると、/ を追加すると相対ディレクトリを示すためです。これは同じエラーを返しました。

これに対する解決策は、「./」が必要だったということでした。は、実行可能ファイルの作業ディレクトリを表します。この作業ディレクトリは、Code::Blocks で実行可能ファイルがビルドされる場所に変更する必要がありました。以下は完全に機能します。

void* hLibrary = dlopen("./libLibrary.so", RTLD_NOW | RTLD_GLOBAL);

これは実際には完全な解決策を示しているわけではありませんが、以下は基本的に私がやっていることと同等です:

void* hLibrary = dlopen("./../../libLibrary.so", RTLD_NOW | RTLD_GLOBAL);

うまくいけば、これで状況が少しよく説明されます。

4

2 に答える 2

17

dlopen(3)の man ページを読んでください (たとえばman dlopen、マシンのターミナルに入力して):

filename にスラッシュ ("/") が含まれている場合は、(相対または絶対) パス名として解釈されます。それ以外の場合、ダイナミック リンカは次のようにライブラリを検索します (詳細については、ld.so(8) を参照してください)。

   o   (ELF only) If the executable file for the calling program
       contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag,
       then the directories listed in the DT_RPATH tag are searched.

   o   If, at the time that the program was started, the environment
       variable LD_LIBRARY_PATH was defined to contain a colon-separated
       list of directories, then these are searched.  (As a security
       measure this variable is ignored for set-user-ID and set-group-ID
       programs.)

   o   (ELF only) If the executable file for the calling program
       contains a DT_RUNPATH tag, then the directories listed in that
       tag are searched.

   o   The cache file /etc/ld.so.cache (maintained by ldconfig(8)) is
       checked to see whether it contains an entry for filename.

   o   The directories /lib and /usr/lib are searched (in that order).

したがって、呼び出す必要があるのは、プラグインをオンにするdlopen("./libLibraryName.so", RTLD_NOW)だけでなく、 ....または追加する必要があります(セキュリティ上の理由からお勧めしません)。dlopen("libLibraryName.so", RTLD_NOW)$LD_LIBRARY_PATH/usr/lib/.LD_LIBRARY_PATH

Jhonnash が答えたように、 dlerrorwhen dlopen(or dlsym) failsの結果を使用して表示する必要があります。

  void* dlh = dlopen("./libLibraryName.so", RTLD_NOW);
  if (!dlh) 
    { fprintf(stderr, "dlopen failed: %s\n", dlerror()); 
      exit(EXIT_FAILURE); };

Linux システム プログラミング全般に関する知識を得るために、Advanced Linux Programmingなどの本を読むことをお勧めします。

于 2013-07-18T06:56:14.533 に答える
2

dlopenについて定義されています。動的ライブラリの dlopen エラーを確認できます。このリンクによる未定義シンボルエラー

于 2013-07-18T06:21:44.570 に答える