1

我想在 Android 项目中使用现有的 C/C++ 库。该库包含对标头(Linux 上的 libresolv)的调用res_query,该resolv.h标头存在于 NDK 中,并且根据Wikipedia的说法,它是 Android 的 Bionic libc 的一部分。

从构建文件中删除显式链接指令后,程序构建和链接正常-lresolv,但 DNS 解析res_query总是失败(返回-1)。

为了进一步检查这个问题,我构建了一个示例程序,只使用了一个调用res_queryAndroid Studio 的示例 C++ 项目:

#include <jni.h>
#include <android/log.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_cpptest_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    unsigned char buf[128];
    const int result = res_query("example.com", C_IN, T_A, buf, 128);
    if (result < 0) {
        herror(NULL);
        __android_log_print(ANDROID_LOG_DEBUG, "CppTest", "DNS Error %d", h_errno);
        return env->NewStringUTF("DNS: Query failed.");
    }
    else
        return env->NewStringUTF("DNS: Query successful.");
}

该程序也总是以result == -1and失败h_errno == 2

我曾尝试同时提供该应用程序android.permission.INTERNETandroid.permission.ACCESS_NETWORK_STATE但均未成功。

使用 Android NDK CMake 工具链将其构建为简单的 C 命令行应用程序,并使用 将其推送到 Android 设备上adb,它也表现出相同的行为。使用默认的 Linux 工具链构建完全相同的代码并在其中执行它可以正常工作并返回有效的 DNS 响应。

我在网上找不到任何resolv.h关于 Android 状态的文档或讨论,除了这个关于 DNS Resolvers 的 AOSP 文档页面,它的名称resolv和状态如下:

出于应用兼容性原因,仿生中的代码继续存在

建议它应该在本机应用程序代码中工作。

我知道大多数 Android 系统不附带resolv.conf文件,这很可能是问题所在。但是说明这一点的防弹文档根本不存在。有谁更具体地知道是否resolv.h 可以在 Android NDK 应用程序中使用系统提供的 DNS 名称服务器设置进行 DNS 查询?

4

1 回答 1

0

API 级别 29 及更高版本不支持res_query 。您可以将 res_query替换为android_res_nqueryandroid_res_nresult

检查https://developer.android.com/ndk/reference/group/networking了解更多详情

于 2021-08-17T15:40:28.870 回答