Android NDK:未定义对“stderr"的引用 [英] Android NDK: undefined reference to 'stderr'

查看:61
本文介绍了Android NDK:未定义对“stderr"的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to use the ASI SDK (prebuilt binary) in an Android application. I am using Android Studio 2.1.3 on Windows 10 with the gradle "experimental plugin" and Android NDK r12b.

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

My JNI test method that calls a basic SDK function looks as follows:

#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 如下所示:

The build.gradle for the app module looks like this:

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 文件:

Since the ASI SDK depends on libusb, I also added the libusb sources as a separate module and imported is as a dependency into the app module. This is the build.gradle file for the libusb module (called "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"])
        }
    }
}

问题:

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

This code builds OK, but when I run it in Genymotion (x86), Android 5, it crashes with a runtime exception:

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

java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "stderr" referenced by "libhello-android-jni.so"..

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

I tried adding supc++ and/or stdc++ to ldFlags, I tried changing the filename extension to cpp and back to c, and I already tried setting the platformVersion to 19 or even 9 in the build.gradle files, but this only resulted in a compile time error saying that stderr is not defined:

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

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: error: ld returned 1 exit status

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

Curiously, this error only occurs for the x86 platform target.

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

I read that stderr etc were removed from Android NDK Headers at a certain point in time because they became real functions in libc, but I'm not quite sure how to solve this problem since setting platformVersion to a lower value (as suggested in some questions) did not help. I would be very grateful for pointers in the right direction.

推荐答案

事实证明我在追求错误的东西.ASI SDK 是针对包含 stderr 作为全局可用符号的 glibc 静态编译的,而仿生(Android libc)不包含它们.

Turns out I was chasing the wrong thing. The ASI SDK was statically compiled against the glibc which contains stderr as globally available symbols, whereas bionic (the Android libc) doesn't contain them.

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

All I had to do was to undefine stderr and created it myself as a linker symbol, so the linker can find it:

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

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

...

这篇关于Android NDK:未定义对“stderr"的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆