次のような状況があります。
動的ライブラリ lib.so を作成しました。このライブラリは、別のスタティック ライブラリ lib.a を使用します。どちらもBoostライブラリを使用しています(CMakeファイルでリンクしています)。(私はJavaプロジェクトでこの動的ライブラリを使用しています)
これは、lib.a から getFilesFromDirectory() を呼び出す、lib.so 内の file.cpp のコードです。
#include "DrawingDetector.h"
#include "../../DrawingDetection.h"
#include <vector>
#include <boost/filesystem/operations.hpp>
using namespace std;
JNIEXPORT void JNICALL Java_DrawingDetector_detectImage( JNIEnv * env, jobject, jstring jMsg)
{
const char* msg = env->GetStringUTFChars(jMsg,0);
vector<File> filesPic = getFilesFromDirectory(msg,0);
env->ReleaseStringUTFChars(jMsg, msg);
}
これは、lib.a からの getFilesFromDirectory() のコードです。
#include <string.h>
#include <iostream>
#include <boost/filesystem/operations.hpp>
#include "DrawingDetection.h"
using namespace std;
using namespace boost;
using namespace boost::filesystem;
vector<File> getFilesFromDirectory(string dir, int status)
{
vector<File> files;
path directoty = path(dir);
directory_iterator end;
if (!exists(directoty))
{
cout<<"There is no such directory or file!"<<endl;
}
for (directory_iterator itr(directoty); itr != end; ++itr)
{
if ( is_regular_file((*itr).path()))
{
//some code
}
}
return files;
}
しかし、私のプロジェクトが lib.so ライブラリを呼び出すと、次のメッセージが表示されます。
java: symbol lookup error: /home/orlova/workspace/kmsearch/Images/branches/DrawingDetection/jni/bin/lib.so: undefined symbol:_ZN5boost11filesystem34path21wchar_t_codecvt_facetEv
私が知ったように、ブーストメソッド「パス」を呼び出そうとすると、lib.aでクラッシュします。しかし、私はすべてのブースト ヘッダーを宣言し、それらを CMake ファイルにリンクしました。ブーストメソッドを認識しない理由を説明できますか?
編集:
私のコンパイラのバージョン gcc 4.6. 4.5 を使用すれば、すべて問題ありません。
また、lib.so の file.cpp でいくつかのブースト メソッドを直接使用すると、すべて正常に動作します。次に例を示します。
JNIEXPORT void JNICALL Java_DrawingDetector_detectImage( JNIEnv * env, jobject, jstring jMsg)
{
const char* msg = env->GetStringUTFChars(jMsg,0);
path directoty = path("/home/orlova");//if I use boost method here
vector<File> filesPic = getFilesFromDirectory(msg,0);// then everything works fine
env->ReleaseStringUTFChars(jMsg, msg);
}
しかし
JNIEXPORT void JNICALL Java_DrawingDetector_detectImage( JNIEnv * env, jobject, jstring jMsg)
{
const char* msg = env->GetStringUTFChars(jMsg,0);
//path directoty = path("/home/orlova");//if I don't use boost method here
vector<File> filesPic = getFilesFromDirectory(msg,0);// then this method causes before-mentioned error!!
env->ReleaseStringUTFChars(jMsg, msg);
}
コンパイラのこの動作をどのように説明できますか?
実行時にエラーが発生することに注意してください。
解決した
問題は、CMake ファイルの *target_link_libraries* のライブラリの順序でした。
違う:
find_library( LIBRARY_MAIN
NAMES lib.a
PATHS ../bin
)
set ( LIB_JNI
jpeg
${OpenCV_LIBS}
${BOOST_LIB}
${LIBRARY_MAIN}//static library is the last in the list of libraries and after boost!
)
target_link_libraries( ${PROJECT} ${LIB_JNI} )
右:
find_library( LIBRARY_MAIN
NAMES lib.a
PATHS ../bin
)
set ( LIB_JNI
${LIBRARY_MAIN}
jpeg
${OpenCV_LIBS}
${BOOST_LIB}//boost library is the last in the list and after static library!
)
target_link_libraries( ${PROJECT} ${LIB_JNI} )