Android NDK链接
我想构build一个调用到C ++后端的Android应用程序。 这个后端使用ZeroMQ进行消息传递。 根据ZeroMQ指南上的android构build页面 ,我已经构build了一个ndk版本6的本地工具链,并使用它来(成功)构buildZeroMQ。
然而,当我用JNI实现构build自己的.so时,似乎无法使所有的东西都正确加载。 具体来说,如果我调用System.LoadLibrary(“zmq”) ,这个成功完成,但如果我然后调用* System.LoadLibrary(“my_lib”)*我总是得到一个UnsatisfiedLinkError抱怨:
Cannot load library reloc_library[1244]: 29 cannot locate zmq_msg_init'...
libmy_lib.so已经被生成了几种不同的方式,每个都没有成功。 生成它后,我总是将libmy_lib.so(以及libzmq.so)复制到我的android项目的文件夹:libs / armeabi /。
# Compile all object files - this part was done for all options /opt/android-toolchain/bin/arm-linux-androideabi-g++ -fpic -c Client_Events.cpp \ Client Wrapper.cpp jni.cpp -I /opt/android-root/include/ -I /my/project/specific/stuff # Option 1 - Don't link the lib in at all /opt/android-toolchain/bin/arm-linux-androideabi-g++ -shared \ -Wl,-soname,libmy_lib.so -o libmy_lib.so jni.o Client_Events.o Client_Wrapper.o # Option 2 - Link ZeroMQ in statically /opt/android-toolchain/bin/arm-linux-androideabi-g++ -shared \ -Wl,-soname,libmy_lib.so -o libmy_lib.so jni.o Client_Events.o Client_Wrapper.o \ libzmq.a libstdc++.a -Wl,--whole-archive # Option 3 - Explicitly link ZeroMQ in dynamically /opt/android-toolchain/bin/arm-linux-androideabi-g++ -shared \ -Wl,-soname,libmy_lib.so -o libmy_lib.so jni.o Client_Events.o Client_Wrapper.o \ -L /opt/android-root/lib/ -lzmq
与这些选项中的每一个,我试图明确调用System.LoadLibrary(“zmq”)加载我自己的库之前,而不是。 没有什么变化的结果。 使用nm确认,至less在选项#2的情况下,丢失的符号* zmq_msg_init确实存在于libmy_lib.so中。
任何想法为什么它不能find链接的ZeroMQ符号?
我刚刚学会了如何编译第二个库,并将其链接到我的主要库在android ndk。 让我看看我对你有没有什么用处。
以下是我如何创build我的第二个库(在我的情况下,我build立子弹物理库和irrlicht渲染引擎作为我的游戏2个独立的库)。
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_C_INCLUDES := HEADER FILES LOCAL_MODULE := bullet LOCAL_SRC_FILES := SRC FILES LOCAL_ARM_MODE := arm LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -O3 -DANDROID_NDK -DDISABLE_IMPORTGL LOCAL_LDLIBS := -ldl -llog include $(BUILD_SHARED_LIBRARY)
然后将你的libxxxx.so(在我的情况下,libbullet.so和libirrlicht.so)复制到你的jni文件夹中。 并在您的主库.mk文件中添加以下内容。
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_C_INCLUDES := (includes for bullet) LOCAL_MODULE := bullet LOCAL_SRC_FILES := libbullet.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_C_INCLUDES := (includes for irrlicht) LOCAL_MODULE := irrlicht LOCAL_SRC_FILES := libirrlicht.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_C_INCLUDES := (includes for bullet + includes for irrlicht + includes for main code) LOCAL_SRC_FILES := main code src files LOCAL_MODULE := gamescript LOCAL_ARM_MODE := arm LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%) -O3 -DANDROID_NDK -DDISABLE_IMPORTGL LOCAL_LDLIBS := -lOpenSLES -landroid -ldl -llog LOCAL_SHARED_LIBRARIES := bullet irrlicht include $(BUILD_SHARED_LIBRARY)
现在,按照正确的顺序将所有库添加到Java代码中。
System.loadLibrary("bullet"); System.loadLibrary("irrlicht"); System.loadLibrary("gamescript");