Question

I have the following situation:

I've created dynamic library lib.so. This library uses another static library lib.a. Both of them use Boost library (I link them in CMake file). (I use this dynamic library in Java project)

This is code of file.cpp in lib.so, which calls getFilesFromDirectory() from lib.a

#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);
}

This is code of getFilesFromDirectory() from lib.a:

#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;
 }

But when my project invokes lib.so library, it raises the following message:

 java: symbol lookup error: /home/orlova/workspace/kmsearch/Images/branches/DrawingDetection/jni/bin/lib.so: undefined symbol:_ZN5boost11filesystem34path21wchar_t_codecvt_facetEv

As I found out it crushes in lib.a, when it tries to invoke boost method "path". But I declared all boost headers, and linked them in CMake file. Can you explain, why it doesn't recognize boost methods?

EDIT:

The version of my compiler gcc 4.6. And if I use 4.5 everything is fine!

Also if I use some boost methods directly in file.cpp in lib.so everything works fine, for example:

 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);
 }

BUT

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);

}

How can you explain this behavior of compiler?

Note, that error occurs in runtime.

SOLVED

The problem was in order of libraries in *target_link_libraries* in CMake file.

WRONG:

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} )

RIGHT:

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} )
Was it helpful?

Solution

It seems that you link Boost.Filesystem dynamically - if so, you have to ensure that this library gets loaded. You can do this either by adding it to LOCAL_LDLIBS line in Android.mk, or by pre-loading it manually before you load lib.so in Java code.

Alternatively, just link Boost (and everything else) statically to lib.so and forget about all this dynamic mess. :)

UPDATE1: with regards to the update you posted -- try putting boost_filesystem.a as the last object in the linker line.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top