Компиляция большой библиотеки C++ в Android NDK с использованием JNI - Вопросы по Makefile

Я пытаюсь скомпилировать библиотеку C++ (VRPN) с парой Java-оболочек для использования в приложении для Android. Используя команду ndk-build, я получаю ошибку "неопределенная ссылка" для первой строки моего файла интерфейса C++, которая ссылается на конструктор для объекта в библиотеке. Я вполне уверен, что мой код правильный - вызов соответствует заголовку метода, и у меня есть и заголовок, и исходные файлы, чтобы убедиться, что он реализован. Я думаю, что проблема в моем файле Android.mk, который в настоящее время ссылается только на мой единственный класс. Таким образом, код создается для компиляции, но не связывается, если не удается найти объектный код для остальной части библиотеки. Я довольно новичок в C++, поэтому я не знаю много о make-файлах, но ни один из "стандартных" make-файлов, которые я видел, не соответствует тем, которые используются в Android NDK, которые, очевидно, скрывают много деталей. Если я правильно понимаю, в "стандартном" make-файле я просто называю выходной файл и какие объектные файлы ему нужны, затем идут объектные файлы и их исходные и заголовочные файлы и т. Д. И т. Д. Я не знаю, как заставить ndk- построить, чтобы создать объектный код и связать остальную часть библиотеки.

Вот мой текущий Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := jni_vrpn_button
LOCAL_SRC_FILES := jni_vrpn_button.cpp

include $(BUILD_SHARED_LIBRARY)

jni_vrpn_button.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jni_VrpnButton */

#ifndef _Included_jni_VrpnButton
#define _Included_jni_VrpnButton
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jni_VrpnButton
 * Method:    vrpn_Button_initialize
 * Signature: (Ljava/lang/String;J)J
 */
JNIEXPORT jlong JNICALL Java_jni_VrpnButton_vrpn_1Button_1initialize
  (JNIEnv *, jobject, jstring, jlong);

/*
 * Class:     jni_VrpnButton
 * Method:    vrpn_button_mainloop
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_jni_VrpnButton_vrpn_1button_1mainloop
  (JNIEnv *, jobject, jlong);

#ifdef __cplusplus
}
#endif
#endif

jni_vrpn_button.cpp:

#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>

#include <jni_vrpn_button.h>
#include <vrpn_Button.h>
#include <vrpn_Connection.h>

/*
 * Class:     jni_VrpnButton
 * Method:    vrpn_Button_initialize
 * Signature: (Ljava/lang/String;J)J
 */
JNIEXPORT jlong JNICALL Java_jni_VrpnButton_vrpn_1Button_1initialize
  (JNIEnv * env, jobject, jstring n, jlong conn)
{
 const char* name = strdup(env->GetStringUTFChars(n, 0));
 vrpn_Button_Example_Server * serv = new vrpn_Button_Example_Server(name, (vrpn_Connection *) conn, 1, 1.0);
 return (long) serv;
}

/*
 * Class:     jni_VrpnButton
 * Method:    vrpn_button_mainloop
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_jni_VrpnButton_vrpn_1button_1mainloop
  (JNIEnv *, jobject, jlong ptr)
{
 ((vrpn_Button_Example_Server *) ptr)->mainloop();
}

Идеи?

Редактировать: забыл опубликовать ошибку:

$ $ CRYSTAX / ndk-build SharedLibrary: libjni_vrpn_button.so / cygdrive / c / Development / android-ndk-r4-windows-crystax-4 / android-ndk-r4-crystax / sources / string / obj / l ocal / armeabi / objs / jni_vrpn_button / jni_vrpn_button.o: в функции Java_jni_VrpnButton_vrpn_1Button_1 initialize': /cygdrive/c/Development/android-ndk-r4-windows-crystax-4/android-ndk-r4-crystax/sources/string/jni/j ni_vrpn_button.cpp:18: undefined reference to vrpn_Button_Example_Server::vrpn_Button_Example_Serve r(char const*, vrpn_Connection*, int, double)' collect2: ld вернул 1 состояние выхода make: *** [/cygdrive/c/Development/android-ndk-r4-windows-crystax-4/android-ndk-r4-crystax/sources/s tring/obj/local/armeabi/libjni_vrpn_button.so] Ошибка 1

1 ответ

Решение

Я полагаю, вы забыли добавить другие файлы cpp, поэтому компоновщик не может найти символы. Поэтому добавьте vrpn_Button.cpp и vrpn_Connection.cpp в ваш Android.mk:

LOCAL_SRC_FILES := \
    jni_vrpn_button.cpp \
    vrpn_Button.cpp \
    vrpn_Connection.cpp

Это одинаково для всех make-файлов, то есть не ограничивается Android.

Другие вопросы по тегам