链接本机函数的未定义引用错误,android

时间:2017-06-07 13:10:01

标签: java android c++ tensorflow java-native-interface

我正在尝试将原生函数链接到java但我收到此错误 -

> Error:(72) undefined reference to `ConvertYUV420SPToARGB8888HalfSize'
> Error:(76) undefined reference to `ConvertYUV420SPToARGB8888'
> Error:(95) undefined reference to `ConvertYUV420SPToARG Error:(102)
> undefined reference to `ConvertYUV420ToARGB8888' Error:(124) undefined
> reference to `ConvertYUV420SPToRGB565' Error:(141) undefined reference
> to `ConvertARGB8888ToYUV420SP' Error:(158) undefined reference to
> `ConvertRGB565ToYUV420SP'

我无法与我的应用成功集成。 这是我调用此函数的java varient的活动:

    public class ClassifierActivity extends CameraActivity implements OnImageAvailableListener {
  static {
    System.loadLibrary("imageutils_jni");
  }
...
...
...

     ImageUtils.convertYUV420ToARGB8888(
              yuvBytes[0],
              yuvBytes[1],
              yuvBytes[2],
              rgbBytes,
              previewWidth,
              previewHeight,
              yRowStride,
              uvRowStride,
              uvPixelStride,
              false);
          computing=false;
          image.close();
        } catch (final Exception e) {
          if (image != null) {
            image.close();
          }

这是函数实例化的方式:

    public static native void convertYUV420ToARGB8888(
      byte[] y,
      byte[] u,
      byte[] v,
      int[] output,
      int width,
      int height,
      int yRowStride,
      int uvRowStride,
      int uvPixelStride,
      boolean halfSize);

这是我的jni.cc文件

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

#include "rgb2yuv.h"
#include "yuv2rgb.h"

#define IMAGEUTILS_METHOD(METHOD_NAME) \
  Java_com_example_harsimar_knp_veggiedetector_ImageUtils_##METHOD_NAME  // NOLINT

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL
IMAGEUTILS_METHOD(convertYUV420SPToARGB8888)(
        JNIEnv* env, jclass clazz, jbyteArray input, jintArray output,
        jint width, jint height, jboolean halfSize);

JNIEXPORT void JNICALL IMAGEUTILS_METHOD(convertYUV420ToARGB8888)(
        JNIEnv* env, jclass clazz, jbyteArray y, jbyteArray u, jbyteArray v,
        jintArray output, jint width, jint height, jint y_row_stride,
        jint uv_row_stride, jint uv_pixel_stride, jboolean halfSize);

JNIEXPORT void JNICALL IMAGEUTILS_METHOD(convertYUV420SPToRGB565)(
        JNIEnv* env, jclass clazz, jbyteArray input, jbyteArray output, jint width,
        jint height);

JNIEXPORT void JNICALL
IMAGEUTILS_METHOD(convertARGB8888ToYUV420SP)(
        JNIEnv* env, jclass clazz, jintArray input, jbyteArray output,
        jint width, jint height);

JNIEXPORT void JNICALL
IMAGEUTILS_METHOD(convertRGB565ToYUV420SP)(
        JNIEnv* env, jclass clazz, jbyteArray input, jbyteArray output,
        jint width, jint height);

#ifdef __cplusplus
}
#endif

JNIEXPORT void JNICALL
IMAGEUTILS_METHOD(convertYUV420SPToARGB8888)(
        JNIEnv* env, jclass clazz, jbyteArray input, jintArray output,
        jint width, jint height, jboolean halfSize) {
    jboolean inputCopy = JNI_FALSE;
    jbyte* const i = env->GetByteArrayElements(input, &inputCopy);

    jboolean outputCopy = JNI_FALSE;
    jint* const o = env->GetIntArrayElements(output, &outputCopy);

    if (halfSize) {
        ConvertYUV420SPToARGB8888HalfSize(reinterpret_cast<uint8_t*>(i),
                                          reinterpret_cast<uint32_t*>(o), width,
                                          height);
    } else {
        ConvertYUV420SPToARGB8888(reinterpret_cast<uint8_t*>(i),
                                  reinterpret_cast<uint8_t*>(i) + width * height,
                                  reinterpret_cast<uint32_t*>(o), width, height);
    }

    env->ReleaseByteArrayElements(input, i, JNI_ABORT);
    env->ReleaseIntArrayElements(output, o, 0);
}

JNIEXPORT void JNICALL IMAGEUTILS_METHOD(convertYUV420ToARGB8888)(
        JNIEnv* env, jclass clazz, jbyteArray y, jbyteArray u, jbyteArray v,
        jintArray output, jint width, jint height, jint y_row_stride,
        jint uv_row_stride, jint uv_pixel_stride, jboolean halfSize) {
    jboolean inputCopy = JNI_FALSE;
    jbyte* const y_buff = env->GetByteArrayElements(y, &inputCopy);
    jboolean outputCopy = JNI_FALSE;
    jint* const o = env->GetIntArrayElements(output, &outputCopy);

    if (halfSize) {
        ConvertYUV420SPToARGB8888HalfSize(reinterpret_cast<uint8_t*>(y_buff),
                                          reinterpret_cast<uint32_t*>(o), width,
                                          height);
    } else {
        jbyte* const u_buff = env->GetByteArrayElements(u, &inputCopy);
        jbyte* const v_buff = env->GetByteArrayElements(v, &inputCopy);

        ConvertYUV420ToARGB8888(
                reinterpret_cast<uint8_t*>(y_buff), reinterpret_cast<uint8_t*>(u_buff),
                reinterpret_cast<uint8_t*>(v_buff), reinterpret_cast<uint32_t*>(o),
                width, height, y_row_stride, uv_row_stride, uv_pixel_stride);

        env->ReleaseByteArrayElements(u, u_buff, JNI_ABORT);
        env->ReleaseByteArrayElements(v, v_buff, JNI_ABORT);
    }

    env->ReleaseByteArrayElements(y, y_buff, JNI_ABORT);
    env->ReleaseIntArrayElements(output, o, 0);
}

JNIEXPORT void JNICALL IMAGEUTILS_METHOD(convertYUV420SPToRGB565)(
        JNIEnv* env, jclass clazz, jbyteArray input, jbyteArray output, jint width,
        jint height) {
    jboolean inputCopy = JNI_FALSE;
    jbyte* const i = env->GetByteArrayElements(input, &inputCopy);

    jboolean outputCopy = JNI_FALSE;
    jbyte* const o = env->GetByteArrayElements(output, &outputCopy);

    ConvertYUV420SPToRGB565(reinterpret_cast<uint8_t*>(i),
                            reinterpret_cast<uint16_t*>(o), width, height);

    env->ReleaseByteArrayElements(input, i, JNI_ABORT);
    env->ReleaseByteArrayElements(output, o, 0);
}

JNIEXPORT void JNICALL
IMAGEUTILS_METHOD(convertARGB8888ToYUV420SP)(
        JNIEnv* env, jclass clazz, jintArray input, jbyteArray output,
        jint width, jint height) {
    jboolean inputCopy = JNI_FALSE;
    jint* const i = env->GetIntArrayElements(input, &inputCopy);

    jboolean outputCopy = JNI_FALSE;
    jbyte* const o = env->GetByteArrayElements(output, &outputCopy);

    ConvertARGB8888ToYUV420SP(reinterpret_cast<uint32_t*>(i),
                              reinterpret_cast<uint8_t*>(o), width, height);

    env->ReleaseIntArrayElements(input, i, JNI_ABORT);
    env->ReleaseByteArrayElements(output, o, 0);
}

JNIEXPORT void JNICALL
IMAGEUTILS_METHOD(convertRGB565ToYUV420SP)(
        JNIEnv* env, jclass clazz, jbyteArray input, jbyteArray output,
        jint width, jint height) {
    jboolean inputCopy = JNI_FALSE;
    jbyte* const i = env->GetByteArrayElements(input, &inputCopy);

    jboolean outputCopy = JNI_FALSE;
    jbyte* const o = env->GetByteArrayElements(output, &outputCopy);

    ConvertRGB565ToYUV420SP(reinterpret_cast<uint16_t*>(i),
                            reinterpret_cast<uint8_t*>(o), width, height);

    env->ReleaseByteArrayElements(input, i, JNI_ABORT);
    env->ReleaseByteArrayElements(output, o, 0);
}

这是我的应用级别gradle文件的方式:

   apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.example.harsimar.kpn_veggiedetector"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
            jni.srcDirs = []
        }
    }
    aaptOptions { noCompress 'pb' }
    lintOptions {
        abortOnError false
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }

    }

    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile files('libs/libandroid_tensorflow_inference_java.jar')
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile 'com.android.support:appcompat-v7:25.3.1'
        compile 'com.android.support.constraint:constraint-layout:1.0.2'
        compile 'com.flurgle:camerakit:0.9.17'
        testCompile 'junit:junit:4.12'
    }
}

cmake文件是这样的:

    cmake_minimum_required(VERSION 3.4.1)

add_library(
             native-lib
             SHARED
             src/main/jni/imageutils_jni.cc
             )


 find_library(
             android-lib
             android
             )
file(
            GLOB SOURCES
            src/main/jni/*.h
            src/main/jni/*.cpp
             )
include_directories( src/main/cpp )
include_directories(src/main/jni)

我在jni文件所在的目录中有所需的标题和其他文件。 请帮助我,提前谢谢!

1 个答案:

答案 0 :(得分:0)

“未定义的引用错误”通常在您不依赖obj文件链接或未按正确顺序链接时发生。你可以检查包含ImageUtils的“.cc”文件是否在你的cmake文件中正确链接了?如果您不确定,请提供以下信息: 1.包含“ImageUtils”的“.cc”文件路径 2.链接“.cc”文件的obj的代码片段。