以下に追加の質問、2011 年 4 月 11 日
C をサポートできるようにする必要がありますが、共有ライブラリ DLL/Sos とテスター プログラムのクロスプラットフォーム セットを C++ で開発しています。ライブラリはオブジェクト コードとしてのみ出荷されますが、テスター プログラムはソースと共に出荷されるので、私たちの顧客はサンプルコードを持つことができます。このため、実行時にロードされるライブラリ、つまり dlopen()/LoadLibraryA() を使用した動的リンクを設計しています。
Umbutu 10.04 で g++ 4.4.3-4 を使用し、Vista/64 (32 ビット モード) で VC++ 2008 を使用しています。
すべてが Windows で問題なく動作するようです (現在)。ただし、Linux でコンパイルすると、特定できないエラーが発生します。
テスターとライブラリには、複数の .cpp と .h でコード化された複数のクラスがあります。メイン エントリ ポイントを除くライブラリ内のクラスとほとんどすべては、名前空間 DISCOVER_NS にあります。
プロジェクトの簡単なスケッチを次に示します。
最初に、認めます。コードが読みやすくなるように、名前の束を短くしました。
発見.cpp
タイプ DiscoverObject の theMainObject と呼ばれるポインタを持つクラス オブジェクトを作成します。
MainObject を呼び出し元プログラムに void* として返す extern "C" 関数があります。
DiscoverObject にはいくつかのメソッドがあり、別の cpp と .h にある他のクラスをインスタンス化します。特定のメソッドの 1 つに Hello() という名前が付けられており、これは期待どおりの動作を行い、"hello" テスト メッセージを出力します。
tester.cpp
ライブラリへのハンドルを取得します
MainObject を返す関数への関数ポインタを取得します。
関数 (ポインター) を実行し、返されたアドレスを void* から DISCOVER_NS::DiscoverObject* aDiscoverObject にキャストします。
aDiscoverObject->Hello() を実行します。
私はコンパイルします:
CC = @g++
gflags = -g3
cflags = -fPIC -Wall -pedantic
lib_linkflags := -shared -fPIC -lstdc++ -lrt -lpthread -rdynamic
tester_linkflags := -ldl -lpthread
定義 = -D_ linux _ -D_DEBUG -D_IPC_ARCH_INTEL=1 -D_THREAD_SAFE
コンパイルすると、次のエラーが表示されます: *Tester.cpp:142: undefined reference to `Discover_NS::DiscoverObject::hello()'*
また、discover.so から他にも未定義の参照エラーがたくさん出ます。たとえば、次のようになります。
SO extern "C"で事実上すべてを作成しようとしました。変わりはない。
次のようなステートメントをdiscover.cppに入れてみました: extern void Discover_NS::OtherClass::method( args ); しかし、それは「クラス外の宣言は定義ではありません」というエラーについてのエラーを私に与えます。
コードを見るのに役立つことはわかっていますが、投稿するために何か小さなものを作り上げる時間が必要です。
この混乱を解決するためのアイデアを提供できる人はいますか?
ありがとう、
ウェス
Dmitry の解決策はすべての修正ではありませんでしたが、解決策に必要な要素でした。メイクファイルを調べたところ、意図せずに重複した行がいくつか見つかりましたが、それらは削除しました。また、コンパイル手順にコード化された -o のパスが間違っていた 2 つの「タイプミス」が見つかりました。壊れた手順で logger.cpp と RemException.cpp がコンパイルされました。
./common/logger.o : ./common/logger.cpp
$(CC) $(gflags) $(cflags) -c $(defines) -I ./common
-I ./EdgeIO -I ./Discover
-o ./common/Debug/logger.o <+++++++++ path to .o was wrong
./common/logger.cpp 2>&1 | tee ./RemKonTester/logger.ERR
その後、本当のバグを見つけました。Discover ディレクトリにあるすべての .cpp をコンパイルしていないという事実を完全に見逃していました。すべての nit-pics を削除するのにかなりの時間がかかりましたが、今ではメイクファイルから問題なくコンパイルできます。
元の質問の新しいバージョン: makefile を介して動作することがわかったので、makefile が行っているのと同じことを行うように Eclipse に指示するにはどうすればよいですか?
ありがとうドミトリー。
ウェス
さて、私の問題はまだここにあります。
Dmitry (@Dmitry) の提案を使用してコードをコンパイルしています。ただ、それらは別の問題を引き起こしているようです。実行時に、ライブラリをメインのテスト プログラムに動的にリンクさせたいと考えています。-l Discover -l EdgeIOをリンクに追加すると、すべてがコンパイルされますが、静的リンクが得られます。
参考までに、未使用の「pi」は、SOに浮動小数点数が含まれているため、浮動小数点サポートでコンパイルされます。呼び出し元が浮動小数点数を使用したい場合に必要です。浮動小数点を含めてg ++をcomkpileに強制するより良い方法はありますか?
Dmitry が見つけてくれた多くのバグを修正した後、次の出力が得られます。
make
./Discover/dllmain.cpp: In function ‘void InitalizeLibraryServices()’:
./Discover/dllmain.cpp:175: warning: unused variable ‘pi’
./EdgeIO/dllMain.cpp: In function ‘void InitalizeLibraryServices()’:
./EdgeIO/dllMain.cpp:158: warning: unused variable ‘pi’
linking RemKonTester
gflags = -g3
tstlinkflags = -ldl -lpthread
defines = -D__linux__ -D_DEBUG -D_IPC_ARCH_INTEL=1 -D_THREAD_SAFE
./RemKonTester/Debug/RemKonTester.o: In function `main':
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:81: undefined
reference to `RemKon_EdgeIO::EdgeIoObject::hello()'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:111: undefined
reference to `RemKon_Discover::DiscoverObject::hello()'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:116: undefined
reference to `RemKon_Discover::DiscoverObject::SetLogLevel(unsigned int)'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:117: undefined
reference to `RemKon_Discover::DiscoverObject::hello()'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:118: undefined
reference to `RemKon_Discover::DiscoverObject::LocalIpAddress(int)'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:122: undefined
reference to `RemKon_Discover::DiscoverObject::RegisterCallback(bool(*)
(void*), void*)'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:123: undefined
reference to `RemKon_Discover::DiscoverObject::Search()'
collect2: ld returned 1 exit status
Eclipse から同じ一連のエラー メッセージが表示されます。
RemKonTester.cpp には、これらの項目が宣言されているすべての .h が含まれています。私は宣言extern "C"でそれらを試しましたが、そうではありませんでした。
助けを期待して、
ウェス