Ann*_*ova 5 c++ java-native-interface linker boost undefined-symbol
我有以下情况:
我创建了动态库lib.so。该库使用另一个静态库lib.a。它们都使用 Boost 库(我将它们链接到 CMake 文件中)。(我在Java项目中使用这个动态库)
这是lib.so中file.cpp的代码,它从lib.a调用getFilesFromDirectory()
#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);
}
Run Code Online (Sandbox Code Playgroud)
这是 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;
}
Run Code Online (Sandbox Code Playgroud)
但是当我的项目调用 lib.so 库时,它会引发以下消息:
java: symbol lookup error: /home/orlova/workspace/kmsearch/Images/branches/DrawingDetection/jni/bin/lib.so: undefined symbol:_ZN5boost11filesystem34path21wchar_t_codecvt_facetEv
Run Code Online (Sandbox Code Playgroud)
正如我发现的,当它尝试调用 boost 方法“path”时,它会在 lib.a 中崩溃。但我声明了所有 boost 标头,并将它们链接到 CMake 文件中。你能解释一下,为什么它不识别 boost 方法吗?
编辑:
我的编译器gcc的版本是4.6。如果我使用 4.5 一切都很好!
另外,如果我直接在 lib.so 的 file.cpp 中使用一些 boost 方法,一切都会正常工作,例如:
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);
}
Run Code Online (Sandbox Code Playgroud)
但
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);
Run Code Online (Sandbox Code Playgroud)
}
你如何解释编译器的这种行为?
请注意,该错误发生在运行时。
解决了
问题出在 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} )
Run Code Online (Sandbox Code Playgroud)
正确的:
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} )
Run Code Online (Sandbox Code Playgroud)
看来您是Boost.Filesystem
动态链接的 - 如果是这样,您必须确保加载该库。您可以通过将其添加到LOCAL_LDLIBS
line in或在加载Java 代码Android.mk
之前手动预加载来实现此目的。lib.so
或者,只需将 Boost(以及其他所有内容)静态链接到lib.so
并忘记所有这些动态混乱。:)
UPDATE1:关于您发布的更新 - 尝试将 boost_filesystem.a 作为链接器行中的最后一个对象。
归档时间: |
|
查看次数: |
1969 次 |
最近记录: |