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

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

问题描述

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

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模块的build.gradle文件(称为"usb"):

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,并且我已经尝试将platformVersion设置为19甚至9在build.gradle文件中,但这只会导致编译时错误,表示未定义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:功能 ASIGetNumOfConnectedCameras:错误:对"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天全站免登陆