Android ndk 使用Android NDK对libssl函数的未定义引用

Android ndk 使用Android NDK对libssl函数的未定义引用,android-ndk,linker,openssl,linker-errors,Android Ndk,Linker,Openssl,Linker Errors,一般来说,我对Android、编译和链接都很陌生。我不知道哪些细节对我的问题很重要,所以我会告诉你一切。如果你看到任何奇怪或不正确的地方,请告诉我 我在Android NDK中构建了libcrypto.so和libssl.so库。我编写的本机代码使用openssl.so中的函数(openssl.so使用libssl.so中的函数)。代码已编译,但在链接时收到“未定义引用”错误: ./obj/local/armeabi/objs/pki_send/pki_send.o: In function `

一般来说,我对Android、编译和链接都很陌生。我不知道哪些细节对我的问题很重要,所以我会告诉你一切。如果你看到任何奇怪或不正确的地方,请告诉我

我在Android NDK中构建了libcrypto.so和libssl.so库。我编写的本机代码使用openssl.so中的函数(openssl.so使用libssl.so中的函数)。代码已编译,但在链接时收到“未定义引用”错误:

./obj/local/armeabi/objs/pki_send/pki_send.o: In function `main':
/home/android/nativeserver/jni/pki_send.c:27: undefined reference to `RSA_generate_key'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/pki_send] Error 1
我在谷歌上搜索,发现一个人和我有同样的问题,她甚至调用了相同的函数(除了这个人不是为Android构建的):。我将引用她文章中与我的问题相关的部分:

当我删除一个参数[指向导致“未定义引用”的函数]时,编译器会说参数太少,而当我添加一个参数时,编译器会说参数太多,因此似乎对正确的函数有“某种”引用。可能有一些链接出错了

我注意到了同样的行为。她通过使用-lssl设置编译解决了她的问题,该设置告诉编译器使用openssl库。为此,我更改了Android.mk文件中的模块,如下所示:

LOCAL_LDLIBS += -ldl
为此:

LOCAL_LDLIBS += -lssl -lcrypto -ldl 
为了安全起见,我加入了-lcrypto,因为libssl依赖于libcrypto。现在,当我运行ndk build时,我收到以下错误:

/home/android/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: cannot find -lssl
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/pki_send] Error 1
此错误表明“ld”找不到libssl.so。我的jni目录中有libcrypto.so和libssl.so。理想情况下,我想找到一种方法,将jni目录添加到“ld”的搜索路径中,但我无法解决这个问题。我试图通过将libssl.so和libcrypto.so添加到以下目录来解决这个问题:/android-ndk-r8/platforms/android-8/arch-arm/usr/lib(我相信“ld”在这里搜索库)。完成此操作后,我再次运行ndk build并收到“undefined reference”错误:

从这里开始,我不知道该如何进行

为了以防万一,下面是我的Android.mk文件中的代码:

LOCAL_PATH := $(call my-dir)
APP_PLATFORM := android-8

include $(CLEAR_VARS)

LOCAL_MODULE    := crypto 
LOCAL_SRC_FILES := libcrypto.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include/

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := ssl 
LOCAL_SRC_FILES := libssl.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include/

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := pki_send.c 
LOCAL_MODULE    := pki_send 
LOCAL_SHARED_LIBRARIES := ssl crypto 
LOCAL_LDLIBS += -lssl -lcrypto -ldl

LOCAL_MODULE_TAGS := optional

include $(BUILD_EXECUTABLE)

编辑:我忘记添加的东西:当我在libcrypto.so中使用本机代码中的函数时,代码编译和链接都很好。似乎我可以使用libcrypto.so中的任何函数。但是,给我带来问题的函数是libssl.so。这可能重要,也可能不重要。

我解决了这个问题。我调用的函数“RSA_generate_key”只存在于不推荐使用的libcrypto.so版本中。我使用的是使用“RSA\u generate\u key\u ex”的较新版本。我通过在libcrypto上执行readelf发现了这一点。因此:

$ ./arm-linux-androideabi-readelf -all ~/nativeserver/jni/libcrypto.so |grep RSA_generate
   679: 00089239   992 FUNC    GLOBAL DEFAULT    7 RSA_generate_key_ex
 10334: 00089239   992 FUNC    GLOBAL DEFAULT    7 RSA_generate_key_ex
该程序仍在编译的原因是,RSA_generate_密钥位于openssl/RSA.h的头文件中,即使库中没有它

$ ./arm-linux-androideabi-readelf -all ~/nativeserver/jni/libcrypto.so |grep RSA_generate
   679: 00089239   992 FUNC    GLOBAL DEFAULT    7 RSA_generate_key_ex
 10334: 00089239   992 FUNC    GLOBAL DEFAULT    7 RSA_generate_key_ex