【问题标题】:Android NDK: undefined reference to 'stderr'Android NDK:未定义对“stderr”的引用
【发布时间】:2017-01-12 08:49:13
【问题描述】:

我想在 Android 应用程序中使用 ASI SDK(预构建的二进制文件)。我在 Windows 10 上使用带有 gradle“实验插件”和 Android NDK r12b 的 Android Studio 2.1.3。

我的调用基本 SDK 函数的 JNI 测试方法如下所示:

#include <jni.h>
#include <stdio.h>
#include <ASICamera2.h>

JNIEXPORT jstring JNICALL
Java_at_wana_androguide_MainActivity_getMsgFromJni(JNIEnv *env, jobject instance)
{
   char str[512];

   int numCams = ASIGetNumOfConnectedCameras();
   snprintf(str, sizeof(str), "Connected cameras: %d", numCams);

   return env->NewStringUTF(str);
}

app 模块的 build.gradle 如下所示:

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion 24
        buildToolsVersion "24.0.2"

        defaultConfig {
            applicationId "at.wana.androguide"
            minSdkVersion.apiLevel 19
            targetSdkVersion.apiLevel 24
            versionCode 1
            versionName "0.1"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles.add(file('proguard-android.txt'))
            }
        }
        ndk {
            moduleName "hello-android-jni"
            abiFilters.add("arm64-v8a")
            abiFilters.add("x86")
            stl "gnustl_static"
        }
        sources {
            main {
                jni {
                    dependencies {
                        library "ASISDK" linkage "static"
                        project ":usb" linkage "shared"
                    }
                }
            }
        }
    }
    repositories {
        libs(PrebuiltLibraries) {
            ASISDK {
                headers.srcDir "src/main/jni/drivers/ASI/include"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("src/main/jni/drivers/ASI/lib/${targetPlatform.getName()}/libASICamera2.a")
                }
            }
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.0'
    compile 'com.squareup:otto:1.3.8'
}

由于 ASI SDK 依赖于 libusb,我还将 libusb 源添加为单独的模块,并将其作为依赖项导入到 app 模块中。这是libusb 模块(称为“usb”)的build.gradle 文件:

apply plugin: "com.android.model.native"

model {
    android {
        compileSdkVersion 24
        buildToolsVersion "24.0.2"

        ndk {
            moduleName "usb"

            CFlags.add("-I${file("src/main/jni")}".toString())
            CFlags.add("-I${file("src/main/jni/os")}".toString())

            ldLibs.addAll(["log"])
        }
    }
}

问题:

此代码构建正常,但是当我在 Genymotion (x86)、Android 5 中运行它时,它会因运行时异常而崩溃:

java.lang.UnsatisfiedLinkError: dlopen failed: 找不到符号 “libhello-android-jni.so”引用的“stderr”..

我尝试将supc++ 和/或stdc++ 添加到ldFlags,我尝试将文件扩展名更改为cpp 并返回c,我已经尝试将platformVersion 设置为19 甚至9 在 build.gradle 文件中,但这只会导致 编译时错误stderr 未定义:

C:\Users\greuff\Documents\devel\AndroGuide\app\src\main\jni\drivers\ASI\lib\x86\libASICamera2.a(ASICamera2.o):ASICamera2.cpp:function ASIGetNumOfConnectedCameras:错误:未定义对“stderr”的引用 collect2.exe:错误:ld 返回 1 个退出状态

奇怪的是,这个错误只发生在x86 平台目标上。

我读到 stderr 等在某个时间点从 Android NDK 标头中删除,因为它们在 libc 中成为真正的函数,但我不太确定如何解决这个问题,因为将 platformVersion 设置为较低的值(如某些问题中所建议的)没有帮助。我将非常感谢您提供正确方向的指示。

【问题讨论】:

    标签: android android-studio gradle android-ndk


    【解决方案1】:

    原来我追错了。 ASI SDK 是针对 glibc 静态编译的,其中包含 stderr 作为全局可用符号,而仿生(Android libc)不包含它们。

    我所要做的就是取消定义 stderr 并自己创建它作为链接器符号,以便链接器可以找到它:

    #include <jni.h>
    #include <stdio.h>
    #include <ASICamera2.h>
    
    #undef stderr
    FILE *stderr = &__sF[2];
    
    ...
    

    【讨论】:

    • “ASI SDK 是针对 glibc 静态编译的”。该库当时是为 Linux 编译的,而不是为 Android 编译的。这对你来说将是一场艰苦的战斗。
    猜你喜欢
    • 2019-01-16
    • 2012-07-18
    • 2019-03-08
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    相关资源
    最近更新 更多