dlopenで*.soファイルをロードできません

このQ&Aのポイント
  • Red Hat Linux EL4.0WSで、dlopenを使用してlibtest.soをロードできません
  • libtest.soをロードすることができず、printTest関数が見つからないエラーが発生します
  • pgCCでlibtest.cppをコンパイルしてlibtest.soを生成し、ldlでtest.cppを実行するとエラーが発生しました
回答を見る
  • ベストアンサー

dlopenで目的の*.soファイルをロードできません

以下C++のテストソース2ファイルをコンパイルし実行したのですが、libtest.soをロードすることが出来ません。OSはRed Hat Linux EL4.0WS、カーネルは2.6.9-5です。原因と思しき点がお分かりの方がいれば、教えて頂けますでしょうか。 ********** ソースファイル1(libtest.cpp) ********** #include <stdio.h> #include <stdlib.h> extern "C" {void printTest();} void printTest(){ printf(" *** SUCCESS!! *** Java - Native Interface test at INOAC\n"); } ********** ソースファイル2(test.cpp) ********** #include <dlfcn.h> #include <stdio.h> #include <stdlib.h> static void (*testFunc)(); int main(){ void *library; const char * error; library = dlopen("libtest.so",RTLD_LAZY); if(library==NULL){ printf("Could not open libtest.so\n"); exit(1); } dlerror(); testFunc = (void (*)())dlsym(library,"printTest"); error = dlerror(); if(error){ printf("Could not find the function printTest\n"); exit(1); } printf("Test from C;\n"); (*testFunc)(); dlclose(library); return 0; } ********** 実行方法 ********** pgCC -fPIC -shared libtest.cpp -o libtest.so pgCC -ldl test.cpp -o test.exe setenv LD_LIBRARY_PATH "." ./test.exe

質問者が選んだベストアンサー

  • ベストアンサー
  • chirubou
  • ベストアンサー率37% (189/502)
回答No.1

dlerror() の使い方を間違えていませんか? library = dlopen("libtest.so",RTLD_LAZY); if(library==NULL){ printf("Could not open libtest.so?n"); printf("dlerror: %s?n", dlerror() ); exit(1); とかするとなんと言ってくるでしょう?

onosendai
質問者

補足

お返事ありがとうございます。ご指摘の通り、dlerror()の使い方が不適切でした。そこで教えて頂いたようソースを修正し、再度実行したところ、以下のようなメッセージが返ってきました。 dlerror: libtest.so: cannot open shared object file: No such file or directory どうしてもlibtest.soを見つけてくれないようです。ちなみにlibtest.soを/libや/usr/lib等にも置いてみましたが変化はありませんでした。

その他の回答 (1)

  • chirubou
  • ベストアンサー率37% (189/502)
回答No.2

「dlerror: libtest.so: cannot open shared object file: No such file or directory どうしてもlibtest.soを見つけてくれないようです。ちなみにlibtest.soを/libや/usr/lib等にも置いてみましたが変化はありませんでした。」 ならば strace を使ってみましょう。 $ strace a.out とすると、全てのシステムコールがどのように呼ばれているかが分かります。これで dlopen の中でどのパスを探しているか分かると思います。 あるいは絶対パスで .so ファイルを指定してみてはいかがでしょう? どうしても相対パスにしたければ man ldconfig を見てください。

onosendai
質問者

お礼

ありがとうございます、原因が分かりました。 libtest.soまでは呼べていたのですが、libtest.soがさらに必要とするdllがありませんでした。とりあえず応急処置として必要なファイルをコピーすることで動きました。今後、コンパイル時のオプションを変更し、抜本的な対策をしたいと思います。使用しているコンパイラの特性をよく理解していないことが本質的な問題でした。 dlerror()の使い方とstrace、大変参考になりました。改めて御礼申し上げます。

関連するQ&A

  • 【VS2008 C++】2つのプロジェクト間で共通の関数を使いたい

    【VS2008 C++】2つのプロジェクト間で共通の関数を使いたい WindowsXP上で visual studio 2008 C++ express editionを 使用しています。 1つのソリューションに2つのプロジェクトをつくり、 その2つに共通の関数を使用させたいのですが、どのように 設定すればよいか教えて頂けませんでしょうか。 ソースの内容は以下のとおりです。 具体的には、mainB.cppでcommon.cppの関数を 呼び出したいです。 //common.cpp #include <stdio.h> void showCommon(){ printf("---common-----\n"); } //common.h #include<stdio.h> void showCommon(); //mainA.cpp #include<stdio.h> #include "common.h" void main(){ printf("---mainA-----\n"); showCommon(); } //mainB.cpp #include<stdio.h> #include "common.h" void main(){ printf("---mainB-----\n"); showCommon(); }

  • 【VC++2008】2つのmain()を1つのプロジェクトに含める方法

    【VC++2008】2つのmain()を1つのプロジェクトに含める方法 現在、WinXP proで、VC++2008 Express Editionを使用しています。 1つのプロジェクトでmain()がある2つのソースを 使い分けたいのですが、その方法を教えて頂けませんでしょうか。 (うろ覚えですが、VC++6.0の頃にはできたと思います。) 例えば、以下のような2つのソースを含んだ1つのプロジェクトの 設定方法を教えて頂きたくお願いします。 ※ソースを見やすくするため、全角スペースを入れています。 //ソース名:main01st.cpp #include<stdio.h> void main(){   printf("main01\n");  } } //ソース名:main02nd.cpp #include<stdio.h> void main(){   printf("main02\n");  } }

  • extern記憶クラス指定子を使う事について

    prg1.cpp----------------------------- #include<stdio.h> void func(void); int gg=5678; int main(void) { printf("main gg=%d\n",gg); func(); return 0; } ---------------------------------- prg2.cpp-------------------------- #include<stdio.h> extern int gg; void func(void) { printf("func gg=%d\n",gg); } ---------------------------------- 以上「prg1.cpp」と「prg2.cpp」という名前のふたつのファイルを作成し、「prg1.cpp」で宣言したグローバル変数を「prg2.cpp」で利用可能にしたいと思っています。 それには、「prg1.cppをコンパイルし、prg2.cppもコンパイルして、両者のオブジェクト(コンパイル後のファイル)をリンクする」と参考書には書いてあったのですが、どのようにしたらリンクされるのかわかりません。 prg.1cpp---------------------- #include<stdio.h> void func(void); int gg=5678; int main(void) { printf("main gg=%d\n",gg); func(); return 0; } #include<stdio.h> extern int gg; void func(void) { printf("func gg=%d\n",gg); } ------------------------------- 以上のように、「prg1.cpp」のファイルに1つにまとめれば、なぜかよくわかりませんが実行できました。 しかし「prg1.cpp」と、「prg2.cpp」をリンクさせてみたいので、教えていただけると嬉しいです。

  • メソッド制御に関して

    C++初心者です。 メソッドのタスク制御??を行いたいのですが、 いまいちよくわかりません。 やりたいことは、下記のソース(検討違いかと思いますが..)のように、 メソッドをリストにして、ループで処理をさせたいというものです。 下記を説明致しますと、TestFunc1()・TestFunc2()というメソッドがあります これらのメソッドをリスト化(programList)して、 メソッド呼び出し元(main)にて、ループをさせてメソッドコールをするというものです。 下記ソースもかなり見当違いであると思われますが、 大変申し訳ございませんが、ご教授よろしくお願いいたします。 ########################################################### # task_Test.cc ########################################################### #include <stdio.h> #include <stdlib.h> #include <unistd.h> // 起動プログラム数 #define PROGRAM_NUM (2) // 呼ばれ元メソッド1 int TestFunc1() {  // 戻り値  int ret = 0;  printf("TestFunc1 Start!\n");  return ret; } // 呼ばれ元メソッド2 int TestFunc2() {  // 戻り値  int ret = 0;  printf("TestFunc2 Start!\n");  return ret; } // 起動プログラムリスト (void*) programList[PROGRAM_NUM]={TestFunc1(),TestFunc2()} int main(int argc,char *argv[]) {  // ループカウンタ  int iCnt;  // ループ処理  for (iCnt=0; iCnt<PROGRAM_NUM; iCnt++)  {   programList[iCnt];  }  return 0; } ###########################################################

  • 分割コンパイルについて

    現在分割コンパイルが分からずに苦戦しています。 下記のリストは構造体を使わなければコンパイラを通すことができましたが、 使うとなぜか通りません。 あれこれ試しましたがどうしても分かりません。 何がおかしいのでしょうか? *define.hで全てのファイルへの定義や宣言を行わせています。 ////////////// //Main.cpp ////////////// #include <stdio.h> #include <conio.h> #include "define.h" int main( void ){ Tmp[0].c = 15; printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); aaa(); bbb(); getch(); return 0; } ////////////////// // A.cpp ///////////////// #include <stdio.h> #include "define.h" void aaa( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // B.cpp ///////////////// #include <stdio.h> #include "define.h" void bbb( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // define.cpp ///////////////// #include "define.h" int a = 10; int b = 20; struct Parameter { int c; }; struct Parameter Tmp[NUM]; ////////////////// // define.h ///////////////// #define NUM 100 extern int a; extern int b; extern struct Parameter Tmp[NUM]; void aaa( void ); void bbb( void );

  • DLL関数を使ったプログラム

     DLL関数を使ったプログラムを動かしたんですが、ERRORが解決できず 困っています。DLLを作成したのはいいのですが、それをLoadLibraryで読み込もうとしても指定したプロシージャが見つからないというエラーになるようです。使用している環境はVisual Studio.NET2003です。  以下はDLLのソースです。 // plug.c // #include <windows.h> #include <stdio.h> __declspec(dllexport) void CALLBACK TestFunc() {    printf("DLLのTestFunc()関数が実行されました。\n"); } これをビルドするとplug.dllとplug.expとplug.libが作成されました。  そしてこれを使用したプログラムが // stab.c // #include <windows.h> #include <stdio.h> typedef void (*TestFunc)(void); void main() {     HMODULE hModule;     DWORD error;     TestFunc funcPointer;     hModule = LoadLibrary(TEXT("plug"));     error = GetLastError();//error値が127     funcPointer = (TestFunc)GetProcAddress(hModule,TEXT("TestFunc"));     funcPointer();     FreeLibrary(hModule);     getchar(); } LoadLibrary関数を使用してアプリのメモリ空間にDLLを読み込もうとしているんですが、ここでハンドルが正確に渡されていないみたいなんです。どうしてこうなるのか分かりません。わかる方いらっしゃったらよろしくお願いします。

  • exitってどう使うの?

    exitを使いたいのですが、プログラムが終了しません。 コンパイルも通りません。 警告:コードは効果を持たない(関数 exit) エラー:ステートメントにセミコロンが無い(関数 exit) と出ます。 windowsでC言語書いています。 入力した数値分「警告」を表示するプログラムなのですが #include <stdio.h> #include <stdlib.h> void exit(int x) { while(x-- > 0){ if(x==0){ printf("警告!\n"); exit 0; } printf("警告!残り%d回。\n", x); } } int main() //警告を表示する回数を変数に代入するプログラムvoid exitのxに渡す。 どうすればexitの位置でプログラムが終了するようにできるのでしょうか。 どなたか教えていただけないでしょうか。

  • 別のファイルの値を得るには?

    ファイルを分割して関数を別のファイルにおいたのですが値を返してもらおうとしても帰ってきません どのようにしたら関数の値を得られますか? 大体このような感じですね ---main.cppの内容--- #include <stdio.h> #include "betu.h" void main( void ){ printf( "%d" , a ); } ---betu.hの内容--- static int a; void betu( void ); ---betu.cppの内容--- void betu( void ){ a = 5; }

  • C++/STLの動作

    お世話になっております。 クラスのインスタンス化時に自身のポインタをストックしようと下記を実行しましたが、 出力が0となり、予想に反していました。 そこで、"test.cpp"の3行目を"main.cpp"に移動すると正しく動作します。 これはどういった動作が原因で起こったのでしょうか? よろしくお願いします。 /// test.h /// #include <vector> class Test { public: Test(){list.push_back(this);} static std::vector<Test*> list; }; /// test.cpp /// #include "test.h" std::vector<Test*> Test::list; /// main.cpp /// #include <stdio.h> #include "test.h" Test test; void main() { printf( "%d\n", test.list.size() ); // "1"と出力されると思ったけど… }

  • 何処が間違っていますか?

    ---------------------------------------------------------------------------------------- #include<stdio.h> #include<stdlib.h> #define MAX_LINE 128 int main(void); int main(void) { char buf[MAX_LINE]; int n; printf("降水確率を入力してください。\n"); gets(buf); n = atoi(buf); printf("降水確率は %d %% です。\n",n); if (n >= 50) { printf("傘を忘れずにね。\n"); } else { printf(傘はいりません。\n"); } printf("いってらっしゃい。\n"); return(0); }