Как связать разделяемую библиотеку с другой разделяемой библиотекой - PullRequest
0 голосов
/ 11 июня 2019

Я пытаюсь создать разделяемую библиотеку, которая реализует JNI (Java Native Interface). Моя общая библиотека использует другую общую библиотеку с именем libPosAPI.so . Но моя общая библиотека неправильно связывает общие функции libPosAPI.so.

В реализации cpp я пытаюсь использовать функцию vatps::PosAPI::sendData() из libPosAPI.so. Вот моя команда сборки:

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

Пожалуйста, направьте меня правильно:)

1 Ответ

2 голосов
/ 11 июня 2019

Давайте расшифруем ваш символ:

$ c++filt _ZN5vatps6PosAPI8sendDataB5cxx11Ev
vatps::PosAPI::sendData[abi:cxx11]()

Итак, ваш код ожидает sendData с std::string с C ++ 11 ABI, тогда как libPosAPI.so обеспечивает sendData с пре-C ++11 ABI std::string.

abi:cxx11 намеки GCC5 и C ++ 11 ABI :

Пользователи, зависящие от сторонних библиотек илиинтерфейсы плагинов, которые все еще используют старый ABI, могут создавать свой код с -D_GLIBCXX_USE_CXX11_ABI=0, и все должно работать нормально.В большинстве случаев будет очевидно, когда этот флаг необходим из-за ошибок компоновщика, жалующихся на неразрешенные символы, включающие __cxx11.

...