Android NDK:对'stderr'的未定义引用

Tho*_*ana 2 android gradle android-ndk android-studio

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

我调用基本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);
}
Run Code Online (Sandbox Code Playgroud)

build.gradleapp模块如下所示:

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'
}
Run Code Online (Sandbox Code Playgroud)

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

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"])
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题:

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

java.lang.UnsatisfiedLinkError:dlopen失败:无法找到"libhello-android-jni.so"引用的符号"stderr".

我尝试添加supc++和/或stdc++ldFlags,我试图改变文件扩展名来cpp和回c,和我已经尝试设置platformVersion到19或文件的build.gradle甚至9,但这只是导致了编译时错误stderr是不定义:

C:\ Users\greuff\Documents\devel\AndroGuide\app\src\main\jni\drivers\ASI\lib\x86\libASICamera2.a(ASICamera2.o):ASICamera2.cpp:function ASIGetNumOfConnectedCameras:error:undefined reference to 'stderr'collect2.exe:错误:ld返回1退出状态

奇怪的是,此错误仅发生在x86平台目标上.

我读了stderr等从Android的NDK头在某一个时间点删除,因为他们成为现实的功能libc,但我不能肯定,因为设置了如何解决这个问题platformVersion,以一个较低的值(如在一些问题的建议)没有救命.我会非常感谢指向正确的方向.

Tho*_*ana 7

事实证明我正在追逐错误的事情.ASI SDK是针对glibc静态编译的,glibc包含stderr全局可用的符号,而bionic(Android libc)不包含它们.

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

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

#undef stderr
FILE *stderr = &__sF[2];

...
Run Code Online (Sandbox Code Playgroud)

  • "ASI SDK是针对glibc进行静态编译的".那个库是为Linux编译的,而不是Android.这对你来说将是一场艰苦的战斗. (4认同)