使用JNI将一个大型的C++库编译为Android NDK - Makefile问题

3
我正在尝试编译一个C++库(VRPN),并配合几个Java包装器在Android应用程序中使用。使用ndk-build命令时,我会得到一个“未定义引用”的错误,该错误指向我的C++接口文件的第一行,该行引用了库中对象的构造函数。我相当确定我的代码是正确的——调用与方法头匹配,并且我有头文件和源文件来验证它是否被实现。我认为问题出在我的Android.mk文件上,它目前只引用了我的单个类。因此,代码似乎可以编译,但一旦无法找到其余库的对象代码,它就无法链接。我对C++还比较陌生,所以不太了解makefile,但我看到的所有“标准”makefile都与Android NDK所使用的不同,后者显然隐藏了很多细节。如果我理解正确,在“标准”makefile中,我只需命名输出文件以及它需要的哪些对象文件,接着是对象文件及其源文件和头文件等等。我不知道如何强制ndk-build创建对象代码并链接其余库。以下是我的当前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: 未定义的引用 到 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个回答

3

我猜您忘记添加其他cpp文件,因此链接器无法找到这些符号。请将vrpn_Button.cpp和vrpn_Connection.cpp添加到您的Android.mk文件中:

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

所有的 makefile 都一样,即不仅限于 Android。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接