如何解决在Android中找不到双重实现?

时间:2019-11-09 17:41:50

标签: java c# android c++ android-studio

java.lang.UnsatisfiedLinkError:对double com.example.tadipta.HandGesture.findInscribedCircleJNI(long,double,double,double,double,double [],double [],long []均未找到实现)         在com.example.tadipta.HandGesture.findInscribedCircleJNI(本机方法)

我想使用openCV 4.1.0构建android应用程序以检测手语和带有C ++ / C项目的某些外部本机方法

这是我的错误:

11-07 03:42:19.233 15585-15971/? E/art: No implementation found for double com.example.tadipta.HandGesture.findInscribedCircleJNI(long, double, double, double, double, double[], double[], long) (tried Java_com_example_tadipta_HandGesture_findInscribedCircleJNI and Java_com_example_tadipta_HandGesture_findInscribedCircleJNI__JDDDD_3D_3DJ)
11-07 03:42:19.233 15585-15971/? E/AndroidRuntime: FATAL EXCEPTION: Thread-114866
    Process: com.example.tadipta, PID: 15585
    java.lang.UnsatisfiedLinkError: No implementation found for double com.example.tadipta.HandGesture.findInscribedCircleJNI(long, double, double, double, double, double[], double[], long) (tried Java_com_example_tadipta_HandGesture_findInscribedCircleJNI and Java_com_example_tadipta_HandGesture_findInscribedCircleJNI__JDDDD_3D_3DJ)
        at com.example.tadipta.HandGesture.findInscribedCircleJNI(Native Method)
        at com.example.tadipta.HandGesture.findInscribedCircle(HandGesture.java:261)
        at com.example.tadipta.MainActivity.makeContours(MainActivity.java:688)
        at com.example.tadipta.MainActivity.onCameraFrame(MainActivity.java:562)
        at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:393)
        at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:373)
        at java.lang.Thread.run(Thread.java:818)

这是我的jni_process.cpp:

#include <jni.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <vector>

using namespace std;
using namespace cv;

extern "C" {
JNIEXPORT jdouble JNICALL Java_com_example_tadipta_HandGesture_findInscribedCircleJNI(JNIEnv* env, jobject obj, jlong imgAddr,
        jdouble rectTLX, jdouble rectTLY, jdouble rectBRX, jdouble rectBRY,
        jdoubleArray incircleX, jdoubleArray incircleY, jlong contourAddr);

JNIEXPORT jdouble JNICALL Java_com_example_tadipta_HandGesture_findInscribedCircleJNI(JNIEnv* env, jobject obj, jlong imgAddr,
        jdouble rectTLX, jdouble rectTLY, jdouble rectBRX, jdouble rectBRY,
        jdoubleArray incircleX, jdoubleArray incircleY, jlong contourAddr)
{
    Mat& img_cpp  = *(Mat*)imgAddr;

    //vector<Point2f>& contour = *(vector<Point2f> *)contourAddr;
    Mat& contourMat = *(Mat*)contourAddr;
    vector<Point2f> contourVec;
    contourMat.copyTo(contourVec);

    double r = 0;
    double targetX = 0;
    double targetY = 0;

    for (int y = (int)rectTLY; y < (int)rectBRY; y++)
    {
        for (int x = (int)rectTLX; x < (int)rectBRX; x++)
        {
            double curDist = pointPolygonTest(contourVec, Point2f(x, y), true);

            if (curDist > r) {
                r = curDist;
                targetX = x;
                targetY = y;
            }
        }
    }

    jdouble outArrayX[] = {0};
    jdouble outArrayY[] = {0};

    outArrayX[0] = targetX;
    outArrayY[0] = targetY;

    env->SetDoubleArrayRegion(incircleX, 0 , 1, (const jdouble*)outArrayX);
    env->SetDoubleArrayRegion(incircleY, 0 , 1, (const jdouble*)outArrayY);
    //Core.circle(img, inCircle, (int)inCircleRadius, new Scalar(240,240,45,0), 2);


    return r;
}
}

这是我的Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include ../../opencv-4.1.0-android-sdk/OpenCV410androidSDK/sdk/native/jni/OpenCV.mk

LOCAL_MODULE    := TAdipta
LOCAL_SRC_FILES := jni_process.cpp
LOCAL_LDLIBS +=  -llog -ldl

include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)

LOCAL_SRC_FILES := \
    jni/onload.cpp \
    jni/info_kunli_androidlibsvmexample_AndroidLibsvmExampleActivity.cpp \
    src/train.cpp \
    src/predict.cpp \
    src/svm/svm-train.cpp \
    src/svm/svm-predict.cpp \
    src/svm/svm.cpp



LOCAL_MODULE    := libsignal
LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

这是我的Application.mk:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-8

这是我的build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.tadipta"
        minSdkVersion 15
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets { main { jni.srcDirs = ['src/main/jni', 'src/main/jniLibs/'] } }
    externalNativeBuild {
        ndkBuild {
            path file('src/main/cpp/Android.mk')
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation project(path: ':opencv')
}

这是我的HandGesture.java的这一部分:

 public native double findInscribedCircleJNI(long imgAddr, double rectTLX, double rectTLY,
                                                double rectBRX, double rectBRY, double[] incircleX, double[] incircleY, long contourAddr);


 void findInscribedCircle(Mat img)
    {


        Point tl = boundingRect.tl();
        Point br = boundingRect.br();

        double[] cirx = new double[]{0};
        double[] ciry = new double[]{0};

        inCircleRadius = findInscribedCircleJNI(img.getNativeObjAddr(), tl.x, tl.y, br.x, br.y, cirx, ciry,
                approxContour.getNativeObjAddr());
        inCircle.x = cirx[0];
        inCircle.y = ciry[0];

        Imgproc.circle(img, inCircle, (int)inCircleRadius, new Scalar(240,240,45,0), 2);
        Imgproc.circle(img, inCircle, 3, Scalar.all(0), -2);
    }

你能告诉我什么问题吗?因为本地方法无法实现

1 个答案:

答案 0 :(得分:0)

此问题已解决 我忘了在local.properties上添加我的ndk源,只是像这样ndk.dir=C\:\\Users\\dipta\\AppData\\Local\\Android\\Sdk\\ndk-bundle添加了您的ndk源,而不是在Application.mk上添加了这段代码APP_STL := c++_shared