1

我遇到了尝试将带有SSL支持的cURL编译到应用程序时遇到的问题。使用Android NDK将共享库和静态库编译到共享库中

到目前为止,我已经成功地将openSSL包编译为libcrypt.so和libssl.so。

我相信我已经成功编译了一个libcurl.a版本的SSL支持,使用配置脚本并通过NDK中的交叉链编译器(在linux环境下)运行它。

现在,我正在尝试在Eclipse下编写一个.so库,该库可以由Android应用程序的Java代码调用。

这是迄今为止的文件结构:

Project Folder ---> jni ---> include ---> curl ---> curl headers 
         |   | 
         |    -> openssl ---> ssl and crypto headers 
         | 
          -> libcrypto.so 
          -> libssl.so 
          -> libcurl.a 
          -> jniProcessRequest.c 
          -> Android.mk 

Android.mk写着:

LOCAL_PATH := $(call my-dir) 
MY_PATH := $(LOCAL_PATH) 
include $(CLEAR_VARS) 
LOCAL_PATH := $(MY_PATH) 

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

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

include $(CLEAR_VARS) 
LOCAL_MODULE := curl 
LOCAL_SRC_FILES := libcurl.a 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/curl/ 
include $(PREBUILT_STATIC_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := JNIProcessRequest 
LOCAL_SRC_FILES := JNIProcessRequest.c 
LOCAL_SHARED_LIBRARIES := crypto ssl 
LOCAL_STATIC_LIBRARIES := curl 
LOCAL_LDLIBS := -llog 

include $(BUILD_SHARED_LIBRARY) 

jniProcessRequest.c:

#include <jni.h> 
#include <stdlib.h> 
#include "include/curl/curl.h" 
#include <android/log.h> 

JNIEXPORT void JNICALL Java_com_example_jniprocessrequest_MainActivity_jniProcessRequest(JNIEnv * env, jobject obje){ 
CURL *conn; 
conn = curl_easy_init(); 
} 

每次我试图编译上面,我在Eclipse中有未定义的参考错误:

make: *** [obj/local/armeabi/libJNIProcessRequest.so] Error 1 
undefined reference to 'curl_easy_init' 

我在想这是某种连锁错误,但我正在努力寻找错误发生的地方。我花了将近两天的时间尝试将共享库放置在不同位置的所有不同方法,使用共享libcurl切换静态libcurl,更改Android.mk文件以及遵循关于如何在Android中使用cURL的教程。

任何帮助将不胜感激!

+0

我找不到任何文件来证实这一点,但我总是看到'LOCAL_EXPORT_C_INCLUDES'指向*文件夹*的路径,而不是单个文件。这可能是值得尝试的'LOCAL_EXPORT_C_INCLUDES:= include/curl' – mbrenon

+0

嗨mbrenon,我已经提出了建议的更改并更新了我的代码,但在编译时我仍然看到相同的两个错误。 – Jake

回答

2

我认为这个问题是由于一个错误构建的libcurl.a静态库引起的。我用一个由GitHub上的用户编译的库替换了我的库,并且不更改任何代码,链接错误消失。

+0

Hi @Jake,你介意共享包含libcurl和所有其他库的项目文件夹(无需你的应用程序源代码)以支持使用android应用程序进行卷曲吗?基本上只是jni文件夹会工作...因为我有麻烦在我的环境下编译libcurl – Thiago

+1

Hi @Thiago,我目前没有访问项目文件夹,但我相信我使用的libcurl.so库来自[link ](https://github.com/liudongmiao/curl-android)或[链接](https://github.com/fuhu/curl-android)。 – Jake

+0

嗨@Jake,谢谢你回到我身边。我将查看您共享的链接,因为我正在使用的libcurl.a可能没有ssl支持,因为它不断返回我不支持的协议错误。 – Thiago

0

您使用curl作为预建模块。

如前所述由NDK文档,你应该小心把它包起来include $(CLEAR_VARS)和(最重要的)下include $(PREBUILT_STATIC_LIBRARY)指令如下:

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 
LOCAL_MODULE := foo-prebuilt 
LOCAL_SRC_FILES := libfoo.a 
include $(PREBUILT_STATIC_LIBRARY) 

右收后照顾include $(CLEAR_VARS)include $(BUILD_SHARED_LIBRARY)来包装你JNIProcessRequest模块。

有关更多详细信息,请参阅docs/PREBUILTS.html部分,您可以在Android NDK文件夹(它看起来像this)中找到该部分。

+0

嗨deltheil,我已经实施了您推荐的更改,并在原始帖子中更新了我的代码以反映新的更改。我还阅读了您推荐的文档。现在我的错误似乎已经改变为某种形式的链接错误,任何想法? – Jake