4

次のような状況があります。

動的ライブラリ 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} )
4

1 に答える 1

3

動的にリンクしているようです。そのBoost.Filesystem場合は、このライブラリがロードされていることを確認する必要があります。LOCAL_LDLIBSこれを行うには、行に追加するか、JavaコードAndroid.mkをロードする前に手動でプリロードします。lib.so

または、Boost(およびその他すべて)を静的にリンクしてlib.so、この動的な混乱をすべて忘れてください。:)

UPDATE1 :投稿した更新に関して-リンカー行の最後のオブジェクトとしてboost_filesystem.aを配置してみてください。

于 2013-01-16T15:40:16.340 に答える