在本地函数的Android应用程序中包含libcurl

时间:2016-04-08 07:21:38

标签: android-ndk libcurl android-permissions

我在一些从Android应用调用的本机例程中使用libcurl时遇到了一个微妙的问题。当我尝试执行get请求时,libcurl说"无法解析主机名。"

我遵循将一些c ++代码放在带有Android.mk文件的jni文件夹中的标准过程。在Android.mk中,我使用$(BUILD_SHARED_LIBRARY)命令创建了一个可以与我的Java Android App一起使用的共享库。 Android应用程序启动,加载共享库,并调用一些函数,最终调用libcurl函数。

我通过在我的共享库中包含libcurl.a以及libssl.a,libcrypto.a和libcares.a来包含libcurl。该过程是为Android.mk中的每个创建一个节,以$(BUILD_SHARED_LIBRARY)结尾。

这些静态库中的每一个都是使用ndk的arm-androideabi-linux交叉编译器为android构建的。最近我添加了最后一个,libcares,试图解决"无法解析主机名"错误,并通过libcares支持重建curl。

现在这里有一个奇怪的部分:为了弄清楚发生了什么,我写了一个小的main(){}测试应用程序并通过一个大的gcc命令将它与这些相同的静态库链接,并且把它作为本机手臂可执行文件在手机上运行。它工作正常!我可以将自己的自签名证书加载到libcurl中,并通过https向我服务器的网址提取请求,效果很好。 我也经历了在x86_64架构中构建东西的整个过程,并让它在那里工作。

我能弄清楚的是,为什么我仍然无法解决主持人问题?"在我的Android应用程序中。

卷曲信息:

curl version:     7.48.0
Host setup:       arm-unknown-linux-androideabi
Install prefix:   /home/cworth/src/libcurl-android_built-w-23/local
Compiler:         arm-linux-androideabi-gcc
SSL support:      enabled (OpenSSL)
SSH support:      no      (--with-libssh2)
zlib support:     enabled
GSS-API support:  no      (--with-gssapi)
TLS-SRP support:  enabled
resolver:         c-ares
IPv6 support:     enabled
Unix sockets support: enabled
IDN support:      no      (--with-{libidn,winidn})
Build libcurl:    Shared=no, Static=yes
Built-in manual:  enabled
--libcurl option: enabled (--disable-libcurl-option)
Verbose errors:   enabled (--disable-verbose)
SSPI support:     no      (--enable-sspi)
ca cert bundle:   no
ca cert path:     no
ca fallback:      no
LDAP support:     no      (--enable-ldap / --with-ldap-lib / --with-lber-lib)
LDAPS support:    no      (--enable-ldaps)
RTSP support:     enabled
RTMP support:     no      (--with-librtmp)
metalink support: no      (--with-libmetalink)
PSL support:      no      (libpsl not found)
HTTP2 support:    disabled (--with-nghttp2)
Protocols:        DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP

SONAME bump:     yes - WARNING: this library will be built with the SONAME
                 number bumped due to (a detected) ABI breakage.
                 See lib/README.curl_off_t for details on this.

Android.mk

CURLINC = ../../libcurl-android_built-w-23/local/include
CURLLIB = ../../libcurl-android_built-w-23/local/lib
LOCAL_PATH := .

include $(CLEAR_VARS)
LOCAL_MODULE = crypto
LOCAL_EXPORT_C_INCLUDES := $(CURLINC)
LOCAL_SRC_FILES := $(CURLLIB)/libcrypto.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE = ssl
LOCAL_EXPORT_C_INCLUDES := $(CURLINC)
LOCAL_SRC_FILES := $(CURLLIB)/libssl.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE = cares
LOCAL_EXPORT_C_INCLUDES := $(CURLINC)
LOCAL_SRC_FILES := $(CURLLIB)/libcares.a
include $(PREBUILT_STATIC_LIBRARY)

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

include $(CLEAR_VARS)
LOCAL_MODULE := mynativelibrary
LOCAL_CFLAGS    := -D_FILE_OFFSET_BITS=64 -pthread -Ijni
LOCAL_CPPFLAGS := -std=c++11
LOCAL_CPP_FEATURES += exceptions rtti
LOCAL_SRC_FILES += {my source files.cpp}
LOCAL_STATIC_LIBRARIES :=  curl cares ssl crypto
LOCAL_LDLIBS := -lz -landroid -llog
include $(BUILD_SHARED_LIBRARY)

MainActivity.java

public class MainActivity extends AppCompatActivity {

    public native String talkToServer();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(!runOnce) {
            runOnce = true;
            Thread.currentThread().setName("Main");
            System.loadLibrary("mynativelibrary");
        }            
....

logcat的:

04-08 02:33:17.023 28328-28506/com.domain.me D/notes: 2016-04-08'T'02:33:17'Z': GET https://example.com:22222/api/notes.json
04-08 02:33:17.023 28328-28506/com.domain.me D/notes: 2016-04-08'T'02:33:17'Z': GET result: Couldn't resolve host name

1 个答案:

答案 0 :(得分:0)

根本不是卷曲问题。我没有从旧版本的应用程序中转移Android权限。然而,最终解决了一堆卷曲构建问题(使用ssl和resolver支持),无论如何我都会遇到这种问题。

我不知道这是否是一个有用的问题,可以留下SO。