I am trying to create shared library which is implementing JNI(Java Native Interface). My shared library is using another shared library which is named libPosAPI.so. But my shared library not correctly linking shared functions of libPosAPI.so
.
In an implementation cpp, i am trying to use function vatps::PosAPI::sendData()
of libPosAPI.so
. Here is my build command:
g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -I. -shared -o libPosAPIJni.so main_ubp_pos_PosAPIJni.cpp
It compiles successfully. Even it does not ask to provide libPosAPI.so
with linker. But when use output shared library(libPosAPIJni.so
), it gives following error undefined symbol: _ZN5vatps6PosAPI8sendDataB5cxx11Ev
. I also provided libPosAPI.so with -L -l
options. The result is same.
Here is my header file. That is a result of javac -h PosAPIJni.java
.
main_ubp_pos_PosAPIJni.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class main_ubp_pos_PosAPIJni */
#ifndef _Included_main_ubp_pos_PosAPIJni
#define _Included_main_ubp_pos_PosAPIJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: main_ubp_pos_PosAPIJni
* Method: sendData
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_main_ubp_pos_PosAPIJni_sendData
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
main_ubp_pos_PosAPIJni.cpp
#include "main_ubp_pos_PosAPIJni.h"
#include "PosAPI.h" // header file of libPosAPI.so
#include <iostream>
using namespace std;
inline string jstring_to_string(JNIEnv* env, jstring string) {
string value;
....
}
// IMPLEMENTATIONS
JNIEXPORT jstring JNICALL Java_main_ubp_pos_PosAPIJni_sendData(JNIEnv* env,
jclass cls) {
string res_sendData = vatps::PosAPI::sendData(); // The PROBLEM IS HERE!!. trying to use function of libPosAPI.so. declared in PosAPI.h
return string_to_jstring(env, res_sendData);
}
The output of nm
command of two shared libraries:
nm -D libPosAPI.so | grep sendData
:
000000000000c3e0 T sendData
000000000000a8dc T _ZN5vatps6PosAPI8sendDataEv
nm -u libPosAPIJni.so | grep sendData
:
U _ZN5vatps6PosAPI8sendDataB5cxx11Ev
Please direct me right way :)
Let's decode your symbol:
$ c++filt _ZN5vatps6PosAPI8sendDataB5cxx11Ev
vatps::PosAPI::sendData[abi:cxx11]()
So, your code expects sendData
with std::string
with C++11 ABI, whereas libPosAPI.so
provides sendData
with pre-C++11 ABI std::string
.
abi:cxx11
hints to GCC5 and the C++11 ABI:
Users that depend on third-party libraries or plugin interfaces that still use the old ABI can build their code with
-D_GLIBCXX_USE_CXX11_ABI=0
and everything should work fine. In most cases, it will be obvious when this flag is needed because of errors from the linker complaining about unresolved symbols involving__cxx11
.