如何link共享库到另一个共享库
How to link shared library to another shared library
我正在尝试创建实现 JNI(Java 本机接口)的共享库。我的共享库正在使用另一个名为 libPosAPI.so 的共享库。但是我的共享库没有正确链接 libPosAPI.so
.
的共享函数
在 cpp 的实现中,我尝试使用 libPosAPI.so
的函数 vatps::PosAPI::sendData()
。这是我的构建命令:
g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -I. -shared -o libPosAPIJni.so main_ubp_pos_PosAPIJni.cpp
编译成功。即使它不要求提供 libPosAPI.so
链接器。但是当使用输出共享库(libPosAPIJni.so
)时,它给出了以下错误undefined symbol: _ZN5vatps6PosAPI8sendDataB5cxx11Ev
。我还为 libPosAPI.so 提供了 -L -l
选项。结果是一样的。
这是我的头文件。这是 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);
}
两个共享库的nm
命令的输出:
nm -D libPosAPI.so | grep sendData
:
000000000000c3e0 T sendData
000000000000a8dc T _ZN5vatps6PosAPI8sendDataEv
nm -u libPosAPIJni.so | grep sendData
:
U _ZN5vatps6PosAPI8sendDataB5cxx11Ev
请告诉我正确的方法:)
让我们解码你的符号:
$ c++filt _ZN5vatps6PosAPI8sendDataB5cxx11Ev
vatps::PosAPI::sendData[abi:cxx11]()
因此,您的代码期望 sendData
和 std::string
以及 C++11 ABI,而 libPosAPI.so
提供 sendData
和 pre-C++11 ABI std::string
.
abi:cxx11
提示 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
.
我正在尝试创建实现 JNI(Java 本机接口)的共享库。我的共享库正在使用另一个名为 libPosAPI.so 的共享库。但是我的共享库没有正确链接 libPosAPI.so
.
在 cpp 的实现中,我尝试使用 libPosAPI.so
的函数 vatps::PosAPI::sendData()
。这是我的构建命令:
g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -I. -shared -o libPosAPIJni.so main_ubp_pos_PosAPIJni.cpp
编译成功。即使它不要求提供 libPosAPI.so
链接器。但是当使用输出共享库(libPosAPIJni.so
)时,它给出了以下错误undefined symbol: _ZN5vatps6PosAPI8sendDataB5cxx11Ev
。我还为 libPosAPI.so 提供了 -L -l
选项。结果是一样的。
这是我的头文件。这是 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);
}
两个共享库的nm
命令的输出:
nm -D libPosAPI.so | grep sendData
:
000000000000c3e0 T sendData
000000000000a8dc T _ZN5vatps6PosAPI8sendDataEv
nm -u libPosAPIJni.so | grep sendData
:
U _ZN5vatps6PosAPI8sendDataB5cxx11Ev
请告诉我正确的方法:)
让我们解码你的符号:
$ c++filt _ZN5vatps6PosAPI8sendDataB5cxx11Ev
vatps::PosAPI::sendData[abi:cxx11]()
因此,您的代码期望 sendData
和 std::string
以及 C++11 ABI,而 libPosAPI.so
提供 sendData
和 pre-C++11 ABI std::string
.
abi:cxx11
提示 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
.