Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
获得;卷发“你无法解决你的主机”;Android中的错误_Android_Android Ndk_Libcurl - Fatal编程技术网

获得;卷发“你无法解决你的主机”;Android中的错误

获得;卷发“你无法解决你的主机”;Android中的错误,android,android-ndk,libcurl,Android,Android Ndk,Libcurl,我已经为android编译了静态libcurl,但不断收到CurlRes代码6,即CURLE\u couldn\u RESOLVE\u HOST Android.mk main-jni.cpp 这段代码是从web源代码下载图像的,但每次调用“curl\u easy\u perform”方法时,都会给出错误代码6。我已使用不同的URL对此进行了检查,但仍然不成功:( “android.permission.INTERNET”和“android.permission.WRITE\u EXTERNA

我已经为android编译了静态libcurl,但不断收到CurlRes代码6,即CURLE\u couldn\u RESOLVE\u HOST

Android.mk
main-jni.cpp 这段代码是从web源代码下载图像的,但每次调用“curl\u easy\u perform”方法时,都会给出错误代码6。我已使用不同的URL对此进行了检查,但仍然不成功:(

“android.permission.INTERNET”和“android.permission.WRITE\u EXTERNAL\u STORAGE”权限已在清单文件中给出


任何解决此问题的指针都会有很大帮助。

请确保将有效的文件名和可写目录路径传递给fopen

我正在

0x00000010处的致命信号11(SIGSEGV)(代码=1)

因为fopen试图打开目录而不是文件

检查Eclipse中LogCat中的日志,或使用adb LogCat查看其他可能的错误

我已经通过以下修改测试了您的代码,它可以正常工作

MainActivity.java

public class MainActivity
{
    private static final String TAG = MainActivity.class.getName();

    static
    {
        try
        {
            System.loadLibrary("mynativelib");
        }
        catch (UnsatisfiedLinkError ex)
        {
            Log.e(TAG, "WARNING: Could not load native library: " + ex.getMessage());
        }
    }

    public static native int DownloadFile(String downloadDirectoryPath);

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

        setContentView(R.layout.activity_main);

        int res = DownloadFile(Environment.getExternalStorageDirectory().getAbsolutePath()
                + File.separator + Environment.DIRECTORY_DOWNLOADS + File.separator 
                + "test.jpg");
        Log.d(TAG, "Result Code: " + res);
    }
}
主jni.cpp

#include <jni.h>
#include <android/log.h>
#include <string>
#include <curl/curl.h>

#define LOG_TAG "native"

#define LOG_INFO(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOG_ERROR(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOG_WARN(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOG_DEBUG(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

#ifdef __cplusplus
extern "C"
{
#endif

    // [FIX for Android 4.2.x]
    // "WARNING: Could not load native library:
    // Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "__exidx_end" referenced by"
    // http://stackoverflow.com/a/14501998/313113
    void __exidx_start()
    {
    }
    void __exidx_end()
    {
    }

    size_t write_data(void *ptr, size_t size, size_t count, FILE *stream)
    {
        size_t written;
        written = fwrite(ptr, size, count, stream);
        LOG_DEBUG("Writing data to file stream %u", written);
        return written;
    }

    jint Java_com_company_awesomeapp_MainActivity_DownloadFile(JNIEnv* env, jobject thiz,
            jstring downloadDirectoryPath)
    {
        CURLcode res;
        res = curl_global_init(CURL_GLOBAL_ALL);

        jint temp = 3;

        LOG_DEBUG("Downloading file");
        const char *nativeDownloadDirPath = env->GetStringUTFChars(downloadDirectoryPath, 0);

        LOG_DEBUG(nativeDownloadDirPath);

        CURL *curl;
        FILE *fp;
        std::string url = "http://travel.paintedstork.com/blog/wp-content/uploads/2012/10/2013-calendar-images-1.jpg";

        curl = curl_easy_init();
        if (curl)
        {
            fp = fopen(nativeDownloadDirPath, "wb");
            res = curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

            LOG_DEBUG("Before write function");
            res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
            LOG_DEBUG("After write function");

            LOG_DEBUG("Before write data");
            res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
            LOG_DEBUG("After write data");

            res = curl_easy_perform(curl);
            curl_easy_cleanup(curl);

            if (fp) fclose(fp);
        }

        env->ReleaseStringUTFChars(downloadDirectoryPath, nativeDownloadDirPath);

        return res;
    }

/**
     * The VM calls JNI_OnLoad when the native library is loaded (for example, through System.loadLibrary).
     * JNI_OnLoad must return the JNI version needed by the native library.
     *
     * @see http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#JNI_OnLoad
     */JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
    {
        JNIEnv* env;
        if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
        {
            return -1;
        }

        // [*] Get jclass with env->FindClass.
        // [*] Register methods with env->RegisterNatives.
        //jniRegisterNativeMethods(env, "dev/android/sample/AndroidNDKSampleActivity", sMethods, NELEM(sMethods));

        return JNI_VERSION_1_6;
    }

/**
     * The VM calls JNI_OnUnload when the class loader containing the native library is garbage collected.
     * This function can be used to perform cleanup operations.
     *
     * Because this function is called in an unknown context (such as from a finalizer),
     * the programmer should be conservative on using Java VM services, and refrain from arbitrary
     * Java call-backs.
     * @see http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#JNI_OnUnload
     */JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved)
    {

    }


#ifdef __cplusplus
}
#endif
#包括
#包括
#包括
#包括
#定义日志标签“本机”
#定义日志信息(…)\uuuuuAndroid\uLog\uPrint(android\uLog\uInfo、日志标签、参数)
#定义日志错误(…)\u android\u日志打印(android\u日志错误、日志标记、参数)
#定义日志警告(…)\uuuuuAndroid日志打印(android日志警告、日志标签、参数)
#定义日志调试(…)\uuuuuAndroid\uLog\uPrint(android\uLog\uDebug、日志标签、参数)
#ifdef_uucplusplus
外部“C”
{
#恩迪夫
//[安卓4.2.x版修复程序]
//“警告:无法加载本机库:
//无法加载库:soinfo\U重新定位(linker.cpp:975):无法找到引用的符号“\uuuuuExidx\uEnd”
// http://stackoverflow.com/a/14501998/313113
void uuu exidx_start()
{
}
void uuu exidx_uend()
{
}
大小写入数据(void*ptr、大小、大小计数、文件*流)
{
书写的大小;
写入=写入(ptr、大小、计数、流);
日志调试(“将数据写入文件流%u”,已写入);
书面回报;
}
jint Java_com_company_awesomeapp_main activity_DownloadFile(JNIEnv*env,jobject thiz,
jstring下载目录路径)
{
卷曲编码;
res=curl\u global\u init(curl\u global\u ALL);
金特温度=3;
日志调试(“下载文件”);
const char*nativeDownloadDirPath=env->GetStringUTFChars(downloadDirectoryPath,0);
日志调试(nativeDownloadDirPath);
卷曲*卷曲;
文件*fp;
std::字符串url=”http://travel.paintedstork.com/blog/wp-content/uploads/2012/10/2013-calendar-images-1.jpg";
curl=curl_easy_init();
if(curl)
{
fp=fopen(nativeDownloadDirPath,“wb”);
res=curl\u easy\u setopt(curl,CURLOPT\u URL,URL.c_str());
日志调试(“写前功能”);
res=curl\u easy\u setopt(curl,CURLOPT\u WRITEFUNCTION,write\u data);
日志调试(“写后功能”);
日志调试(“写入数据前”);
res=curl\u easy\u setopt(curl,CURLOPT\u WRITEDATA,fp);
日志调试(“写入数据后”);
res=旋度(curl)\u容易执行(curl);
旋度\轻松\清洁(旋度);
if(fp)fclose(fp);
}
env->ReleaseStringUTFChars(下载目录路径,nativeDownloadDirPath);
返回res;
}
/**
*当加载本机库时(例如,通过System.loadLibrary),VM调用JNI_OnLoad。
*JNI_OnLoad必须返回本机库所需的JNI版本。
*
*@见http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#JNI_OnLoad
*/JNIEXPORT jint JNI_OnLoad(JavaVM*vm,void*reserved)
{
JNIEnv*env;
if(vm->GetEnv(重新解释cast(&env),JNI\u版本1\u 6)!=JNI\u OK)
{
返回-1;
}
//[*]使用env->FindClass获取jclass。
//[*]使用env->RegisterNatives注册方法。
//jniRegisterNativeMethods(env,“dev/android/sample/AndroidNDKSampleActivity”,sMethods,NELEM(sMethods));
返回JNI_版本_1_6;
}
/**
*当包含本机库的类装入器被垃圾收集时,VM调用JNI_OnUnload。
*此函数可用于执行清理操作。
*
*因为此函数是在未知上下文中调用的(例如从终结器调用),
*程序员在使用JavaVM服务时应该保守,不要随意使用
*Java回调。
*@见http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#JNI_OnUnload
*/JNIEXPORT void JNI_OnUnload(JavaVM*vm,void*reserved)
{
}
#ifdef_uucplusplus
}
#恩迪夫

该文件将保存在:/storage/emulated/0/Download/test.jpg

如果您在编译
libcurl
时不使用线程解析程序(CMake选项
启用线程解析程序
),而目标Android API级别低于23,也会发生这种情况

问题是因为
CMake/CurlTests.c的实现包含以下行:

\ifndef gethostbyaddr\r
(无效)gethostbyaddr\r;
#恩迪夫
但是,如果您在Android NDK中检查
netdb.h
头,您将看到

\if\uuuuuuu ANDROID\uuuAPI\uuuuuu>=23
int gethostbyaddr\u r(const void*\uu addr,socklen\u t\uu长度,int类型,struct hostent*\uu ret,char*\uu buf,size\u t\uu buf\u size,struct hostent**\uu结果,int*\uu h\u errno\uptr)在(23)中引入;
#endif/*.\uuuuuu ANDROID\uAPI\uuuuuu>=23*/
这意味着当针对比棉花糖更老的Android时,此功能不可用。这是有问题的,因为测试
HAVE_GETHOSTBYNAME_R
成功,而测试
HAVE_GETHOSTBYNAME_R_6
失败(但应该成功),并出现以下错误(可在
CMakeError.log
中观察到):

这导致函数
Curl\u ip中没有运算行为
public class MainActivity
{
    private static final String TAG = MainActivity.class.getName();

    static
    {
        try
        {
            System.loadLibrary("mynativelib");
        }
        catch (UnsatisfiedLinkError ex)
        {
            Log.e(TAG, "WARNING: Could not load native library: " + ex.getMessage());
        }
    }

    public static native int DownloadFile(String downloadDirectoryPath);

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

        setContentView(R.layout.activity_main);

        int res = DownloadFile(Environment.getExternalStorageDirectory().getAbsolutePath()
                + File.separator + Environment.DIRECTORY_DOWNLOADS + File.separator 
                + "test.jpg");
        Log.d(TAG, "Result Code: " + res);
    }
}
#include <jni.h>
#include <android/log.h>
#include <string>
#include <curl/curl.h>

#define LOG_TAG "native"

#define LOG_INFO(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOG_ERROR(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOG_WARN(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOG_DEBUG(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

#ifdef __cplusplus
extern "C"
{
#endif

    // [FIX for Android 4.2.x]
    // "WARNING: Could not load native library:
    // Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "__exidx_end" referenced by"
    // http://stackoverflow.com/a/14501998/313113
    void __exidx_start()
    {
    }
    void __exidx_end()
    {
    }

    size_t write_data(void *ptr, size_t size, size_t count, FILE *stream)
    {
        size_t written;
        written = fwrite(ptr, size, count, stream);
        LOG_DEBUG("Writing data to file stream %u", written);
        return written;
    }

    jint Java_com_company_awesomeapp_MainActivity_DownloadFile(JNIEnv* env, jobject thiz,
            jstring downloadDirectoryPath)
    {
        CURLcode res;
        res = curl_global_init(CURL_GLOBAL_ALL);

        jint temp = 3;

        LOG_DEBUG("Downloading file");
        const char *nativeDownloadDirPath = env->GetStringUTFChars(downloadDirectoryPath, 0);

        LOG_DEBUG(nativeDownloadDirPath);

        CURL *curl;
        FILE *fp;
        std::string url = "http://travel.paintedstork.com/blog/wp-content/uploads/2012/10/2013-calendar-images-1.jpg";

        curl = curl_easy_init();
        if (curl)
        {
            fp = fopen(nativeDownloadDirPath, "wb");
            res = curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

            LOG_DEBUG("Before write function");
            res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
            LOG_DEBUG("After write function");

            LOG_DEBUG("Before write data");
            res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
            LOG_DEBUG("After write data");

            res = curl_easy_perform(curl);
            curl_easy_cleanup(curl);

            if (fp) fclose(fp);
        }

        env->ReleaseStringUTFChars(downloadDirectoryPath, nativeDownloadDirPath);

        return res;
    }

/**
     * The VM calls JNI_OnLoad when the native library is loaded (for example, through System.loadLibrary).
     * JNI_OnLoad must return the JNI version needed by the native library.
     *
     * @see http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#JNI_OnLoad
     */JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
    {
        JNIEnv* env;
        if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
        {
            return -1;
        }

        // [*] Get jclass with env->FindClass.
        // [*] Register methods with env->RegisterNatives.
        //jniRegisterNativeMethods(env, "dev/android/sample/AndroidNDKSampleActivity", sMethods, NELEM(sMethods));

        return JNI_VERSION_1_6;
    }

/**
     * The VM calls JNI_OnUnload when the class loader containing the native library is garbage collected.
     * This function can be used to perform cleanup operations.
     *
     * Because this function is called in an unknown context (such as from a finalizer),
     * the programmer should be conservative on using Java VM services, and refrain from arbitrary
     * Java call-backs.
     * @see http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#JNI_OnUnload
     */JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved)
    {

    }


#ifdef __cplusplus
}
#endif
/path/to/curl/CMake/CurlTests.c:128:9: error: use of undeclared identifier 'gethostbyaddr_r'
  (void)gethostbyaddr_r;
        ^
1 error generated.