OpenCv with Android studio 1.3+ using new gradle - undefined reference [英] OpenCv with Android studio 1.3+ using new gradle - undefined reference

查看:17
本文介绍了OpenCv with Android studio 1.3+ using new gradle - undefined reference的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用带有新的 ndk 支持的 Android Studio 1.3+ 的原生 OpenCv 2.4.11(3.0.0 也可以)时遇到问题.所有关于 .mk 文件的教程,但我想将它与新的实验性 gradle 一起使用.
使用 Kiran 回答 OpenCV in Android Studio我在java中实现了正常工作.我还更改了
gradle-wrapper.properties:

distributionUrl=https://services.gradle.org/distributions/gradle-2.5-all.zip

build.gradle(应用程序):

类路径 'com.android.tools.build:gradle-experimental:0.2.0'



build.gradle(module):

应用插件:'com.android.model.application'模型 {安卓 {compileSdkVersion = 23buildToolsVersion = "23.0.0"defaultConfig.with {applicationId = "android.overloaded.nativetestv4"minSdkVersion.apiLevel = 18targetSdkVersion.apiLevel = 23版本代码 = 1版本名称 = "1.0"}}安卓.ndk{模块名称 = 我的模块"ldLibs += ['日志']cppFlags += "-std=c++11"cppFlags += "-fexceptions"cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()ldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"]//添加 zstl = "stlport_static"//"gnustl_shared" 改为stlport static}android.buildTypes {发布 {minifyEnabled = 假proguardFiles += file('proguard-rules.pro')}}android.productFlavors {//添加所有productFlavors代码创建(手臂"){ndk.with {abiFilters += "armeabi"文件 curDir = file('./')curDir = 文件(curDir.absolutePath)String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi\"//"-L" +ldLibs += libsDir + "libnative_camera_r4.3.0.so"ldLibs += libsDir + "libopencv_contrib.a"ldLibs += libsDir + "libopencv_core.a"ldLibs += libsDir + "libopencv_highgui.a"ldLibs += libsDir + "libopencv_imgproc.a"ldLibs += libsDir + "libopencv_info.so"ldLibs += libsDir + "libopencv_java.so"ldLibs += libsDir + "libopencv_legacy.a"ldLibs += libsDir + "libopencv_ml.a"ldLibs += libsDir + "libopencv_ts.a"}}创建(armv7"){ndk.with {abiFilters += "armeabi-v7a"文件 curDir = file('./')curDir = 文件(curDir.absolutePath)字符串 libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi-v7a\"//"-L" +ldLibs += libsDir + "libnative_camera_r4.3.0.so"ldLibs += libsDir + "libopencv_contrib.a"ldLibs += libsDir + "libopencv_core.a"ldLibs += libsDir + "libopencv_highgui.a"ldLibs += libsDir + "libopencv_imgproc.a"ldLibs += libsDir + "libopencv_info.so"ldLibs += libsDir + "libopencv_java.so"ldLibs += libsDir + "libopencv_legacy.a"ldLibs += libsDir + "libopencv_ml.a"ldLibs += libsDir + "libopencv_ts.a"}}创建(胖"){}}依赖{编译文件树(包括:['*.jar'],目录:'libs')编译'com.android.support:appcompat-v7:23.0.0'编译项目(':openCVLibrary2411')}

通过这些更改,我可以在 jni 文件夹下的 c++ 文件中调用我的原生虚拟函数.CLion 还支持 #include <opencv2/core/core.hpp> 和其他...当我声明 cv::Mat mat;给我这个错误:

链接 libmymodule.so 时链接器失败.C:DevAndroidOpenCV-android-sdksdk
ativejniinclude/opencv2/core/mat.hpp:278: 错误:未定义的对 'cv::fastFree(void*)' 的引用C:DevAndroidOpenCV-android-sdksdk
ativejniinclude/opencv2/core/mat.hpp:367: 错误: 未定义对 'cv::Mat::deallocate()' 的引用collect2.exe:错误:ld 返回 1 退出状态

c++代码:

#include <jni.h>#include <向量>#include <字符串>#include "helpers.h"#include <opencv2/core/core.hpp>//这是CLion支持的#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/highgui/highgui.hpp>使用命名空间标准;外部C"{JNIEXPORT jstring JNICALLJava_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass 类型) {简历::垫垫;//导致错误字符串 s = "Cpp v1 - succ";返回 env->NewStringUTF(s.data());}}

更新

- 将z"添加到 ldLibs
- 添加了 android.productFlavors 块

现在编译成功,应用程序启动第二次,然后崩溃并显示此消息
事件日志:

IllegalArgumentException:启动本机调试会话时出错:无法在设备 huawei-huawei_y530_u00-64a6513ccd8e 上找到 android.overloaded.nativetestv4 的进程

调试信息:

重新启动 ADB 集成并重试等待进程:android.overloaded.nativetestv4设备外壳命令:run-as android.overloaded.nativetestv4 mkdir -p/data/data/android.overloaded.nativetestv4/lldb/bin设备外壳命令:cat/data/local/tmp/lldb-server |作为 android.overloaded.nativetestv4 运行 sh -c 'cat >/data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server;chmod 700/data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server'设备外壳命令:rm/data/local/tmp/lldb-server设备外壳命令:cat/data/local/tmp/start_lldb_server.sh |作为 android.overloaded.nativetestv4 运行 sh -c 'cat >/data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh;chmod 700/data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh'设备外壳命令:rm/data/local/tmp/start_lldb_server.sh现在启动本机调试会话启动本机调试会话时出错:java.lang.IllegalArgumentException: Unable to find process for android.overloaded.nativetestv4 on device huawei-huawei_y530_u00-64a6513ccd8e

日志:

A/libc: 致命信号 11 (SIGSEGV) at 0x00000000 (code=1), thread 3077 (ed.nativetestv4)

解决方案

经过几周的痛苦,我成功了.这是我对 Android Studio 1.3.1、OpenCv 2.4.11 的正确代码.首先你应该这样做 OpenCV in Android Studio(对于项目和 opencv 提取文件夹,不要使用包含空格的路径)然后,让 opencv 成为本机:

gradle-wrapper.properties:

distributionUrl=https://services.gradle.org/distributions/gradle-2.5-all.zip

build.gradle(应用程序):

类路径 'com.android.tools.build:gradle-experimental:0.2.0'

build.gradle(模块):

应用插件:'com.android.model.application'模型 {安卓 {compileSdkVersion = 23buildToolsVersion = "23.0.0"defaultConfig.with {applicationId = "android.overloaded.nativetestv4"minSdkVersion.apiLevel = 18targetSdkVersion.apiLevel = 23版本代码 = 1版本名称 = "1.0"}}安卓.ndk{模块名称 = 我的模块"ldLibs += ['日志']cppFlags += "-std=c++11"cppFlags += "-fexceptions"cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()//ldFlags += linkOptldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"]//, "ibopencv_core"stl = "gnustl_shared"//"gnustl_static"//"gnustl_shared"//"stlport_static"}android.buildTypes {发布 {minifyEnabled = 假proguardFiles += file('proguard-rules.pro')}}android.productFlavors {创建(手臂"){ndk.with {abiFilters += "armeabi"文件 curDir = file('./')curDir = 文件(curDir.absolutePath)String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi\"//"-L" +ldLibs += libsDir + "libnative_camera_r4.3.0.so"ldLibs += libsDir + "libopencv_contrib.a"ldLibs += libsDir + "libopencv_core.a"ldLibs += libsDir + "libopencv_highgui.a"ldLibs += libsDir + "libopencv_imgproc.a"ldLibs += libsDir + "libopencv_info.so"ldLibs += libsDir + "libopencv_java.so"ldLibs += libsDir + "libopencv_legacy.a"ldLibs += libsDir + "libopencv_ml.a"ldLibs += libsDir + "libopencv_ts.a"}}创建(armv7"){ndk.with {abiFilters += "armeabi-v7a"文件 curDir = file('./')curDir = 文件(curDir.absolutePath)字符串 libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi-v7a\"//"-L" +ldLibs += libsDir + "libnative_camera_r4.3.0.so"ldLibs += libsDir + "libopencv_contrib.a"ldLibs += libsDir + "libopencv_core.a"ldLibs += libsDir + "libopencv_highgui.a"ldLibs += libsDir + "libopencv_imgproc.a"ldLibs += libsDir + "libopencv_info.so"ldLibs += libsDir + "libopencv_java.so"ldLibs += libsDir + "libopencv_legacy.a"ldLibs += libsDir + "libopencv_ml.a"ldLibs += libsDir + "libopencv_ts.a"}}创建(x86"){ndk.with {abiFilters += "x86"}}创建(mips"){ndk.with {abiFilters += "mips"}}创建(胖"){}}}依赖{编译文件树(包括:['*.jar'],目录:'libs')编译'com.android.support:appcompat-v7:23.0.0'编译项目(':openCVLibrary2411')}

.cpp

#include <jni.h>#include <向量>#include <字符串>#include "helpers.h"#include <opencv2/core/core.hpp>使用命名空间标准;#ifdef __cplusplus外部C"{#万一JNIEXPORT jstring JNICALLJava_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass 类型) {cv::Mat mat(33,22, 1);string s = "Cpp v1 - succ, rows#:" + Helpers::ToStringNum(mat.rows);助手::日志;返回 env->NewStringUTF(s.data());}}

.java

package android.overloaded.nativetestv4;导入android.support.v7.app.AppCompatActivity;导入android.os.Bundle;导入 android.view.Menu;导入android.view.MenuItem;导入 android.widget.TextView;导入 android.widget.Toast;公共类 MainActivity 扩展 AppCompatActivity{静止的 {System.loadLibrary("mymodule");}公共静态原生字符串 FuncV1();@覆盖protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Toast.makeText(this, FuncV1(), Toast.LENGTH_LONG).show();((TextView)findViewById(R.id.txtInfo)).setText(FuncV1());}

Android Studio 1.5.1、OpenCV 3.1 更新
1. 首先你应该这样做 OpenCV in Android Studio (不要使用包含白色的路径空间,用于项目和 opencv 提取文件夹),之后您应该有正常工作的 Java 应用程序
2.修改项目根目录下的build.gradle:

buildscript {存储库{中心()}依赖{类路径com.android.tools.build:gradle-experimental:0.4.0"//注意:不要将您的应用程序依赖项放在这里;他们属于//在单个模块 build.gradle 文件中}}所有项目{存储库{中心()}}任务清理(类型:删除){删除 rootProject.buildDir}

  1. 更改 gradle-wrapper.properties:

<块引用>

distributionBase=GRADLE_USER_HOME分布路径=包装/分布zipStoreBase=GRADLE_USER_HOMEzipStorePath=包装器/distsdistributionUrl=https://services.gradle.org/distributions/gradle-2.8-all.zip

  1. 修改opencv模块中的build.gradle:

    <块引用>

    应用插件:'com.android.model.library'模型 {安卓 {compileSdkVersion = 23buildToolsVersion = "23.0.2"defaultConfig.with {minSdkVersion.apiLevel = 11targetSdkVersion.apiLevel = 23}}android.buildTypes {发布 {minifyEnabled = 假proguardFiles.add(file("proguard-rules.txt"))}}}

  2. 更改 app 模块中的 build.gradle:

    <块引用>

    应用插件:'com.android.model.application'模型 {安卓 {compileSdkVersion = 23buildToolsVersion = "23.0.2"defaultConfig.with {applicationId = "android.overloaded.opencv31v1"//包名minSdkVersion.apiLevel = 11targetSdkVersion.apiLevel = 23版本代码 = 1版本名称 = "1.0"}}安卓.ndk {moduleName = "native"//C++ 模块的名称,用于 System.loadLibrary("native")cppFlags.add("-std=c++11")//添加规定以允许 C++11 功能cppFlags.add("-fexceptions")//你的 OPENCV 目录!!!cppFlags.add("-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString())ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "z"])stl = "gnustl_shared"}android.buildTypes {发布 {minifyEnabled = 假proguardFiles.add(file("proguard-rules.txt"))}}android.productFlavors {创建(手臂"){ndk.with{abiFilters.add("armeabi")文件 curDir = file('./')curDir = 文件(curDir.absolutePath)字符串 libsDir = curDir.absolutePath + "\src\main\jniLibs\armeabi\"ldLibs.add(libsDir + "libopencv_core.a")ldLibs.add(libsDir + "libopencv_highgui.a")ldLibs.add(libsDir + "libopencv_imgproc.a")ldLibs.add(libsDir + "libopencv_java3.so")ldLibs.add(libsDir + "libopencv_ml.a")}}创建(armv7"){ndk.with {abiFilters.add("armeabi-v7a")文件 curDir = file('./')curDir = 文件(curDir.absolutePath)字符串 libsDir = curDir.absolutePath + "\src\main\jniLibs\armeabi-v7a\"ldLibs.add(libsDir + "libopencv_core.a")ldLibs.add(libsDir + "libopencv_highgui.a")ldLibs.add(libsDir + "libopencv_imgproc.a")ldLibs.add(libsDir + "libopencv_java3.so")ldLibs.add(libsDir + "libopencv_ml.a")ldLibs.add(libsDir + "libopencv_ts.a")}}}android.sources{主要的{jni{来源{srcDirs += ['src/main/jniMy']}}}}}依赖{编译 fileTree(dir: "libs", include: [$/*.jar/$])compile "com.android.support:appcompat-v7:23.1.1"//不要使用23.2.0编译项目(:openCVLibrary310")}

  3. 创建目录 app/src/main/jniMy,这是存放你的 .cpp 文件的地方

  4. 可选择在 jniMy 中创建文件 chelper.c,使用以下代码:

    <块引用>

    #ifndef OPENCV31V1_CHELPER_H#define OPENCV31V1_CHELPER_H#include <jni.h>#include <向量>#include <字符串>#include <流>#include <android/log.h>使用命名空间标准;类助手{上市:模板<typename T>静态字符串 ToS​​tringNum(T tNumber){ostringstream ostrStream;ostrStream <

  5. 在 jniMy 中创建文件 native_exporter.cpp,代码如下:

    <块引用>

    #include <jni.h>#include <字符串>#include <opencv2/core/core.hpp>#include chelper.h"外部C"{JNIEXPORT jstring JNICALLJava_android_overloaded_opencv31v1_MainActivity_FuncV1(JNIEnv *env,jclass类型){cv::Mat mat(33,22, CV_32FC2);string s = "Cpp v1 - succ, rows#:" +Helpers::ToStringNum(mat.rows);助手::日志;自动 i = 5;对于(int i2:{1,3,5}){Helpers::Log(Helpers::ToStringNum(i2));}返回 env->NewStringUTF(s.data());}}

  6. MainActivity.java 中的代码:

    <块引用>

    package android.overloaded.opencv31v1;导入android.os.Bundle;导入android.support.v7.app.AppCompatActivity;导入android.util.Log;导入android.view.SurfaceView;导入 android.widget.TextView;导入 android.widget.Toast;导入 org.opencv.android.CameraBridgeViewBase;导入 org.opencv.core.CvType;导入 org.opencv.core.Mat;公共类 MainActivity 扩展 AppCompatActivity 实现 CameraBridgeViewBase.CvCameraViewListener2{私有静态无效日志(字符串 sMsg){Log.i("My", "MainActivity." + sMsg);}静止的{System.loadLibrary("opencv_java3");System.loadLibrary("native");}公共原生字符串 FuncV1();JavaCameraViewCustom2 _javaCameraView;//类似于JavaCameraView@覆盖protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if(getSupportActionBar() != null)getSupportActionBar().hide();字符串 sRes = FuncV1();Toast.makeText(this, sRes, Toast.LENGTH_LONG).show();((TextView)findViewById(R.id.txtInfo)).setText(sRes);_javaCameraView = (JavaCameraViewCustom2)findViewById(R.id.cameraView);_javaCameraView.setVisibility(SurfaceView.VISIBLE);_javaCameraView.setCvCameraViewListener(this);}@覆盖受保护的无效 onResume(){超级.onResume();_javaCameraView.enableView();}@覆盖受保护的无效 onPause(){超级.onPause();_javaCameraView.disableView();}垫子_imgBgrTemp;@覆盖公共无效 onCameraViewStarted(int 宽度,int 高度){_imgBgrTemp = new Mat(高度,宽度, CvType.CV_8UC4);}@覆盖公共无效 onCameraViewStopped(){_imgBgrTemp.release();}@覆盖公共垫 onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame){_imgBgrTemp = inputFrame.rgba();返回_imgBgrTemp;}}

Android Studio 会要求你更改 jdk,它也会安装新的 gradle,你应该做它要求的一切.

I'm having trouble using native OpenCv 2.4.11 (3.0.0 is also ok) with Android Studio 1.3+, with new ndk support. All tutorials about .mk files, but I want to use it with new experimental gradle.
Using Kiran answer OpenCV in Android Studio I achived to work fine in java. Also I have changed
gradle-wrapper.properties:

distributionUrl=https://services.gradle.org/distributions/gradle-2.5-all.zip

build.gradle(application):

classpath 'com.android.tools.build:gradle-experimental:0.2.0'



build.gradle(module):

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.0"

        defaultConfig.with {
            applicationId = "android.overloaded.nativetestv4"
            minSdkVersion.apiLevel = 18
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }
    }

    android.ndk{
        moduleName = "mymodule"
        ldLibs += ['log']
        cppFlags += "-std=c++11" 
        cppFlags += "-fexceptions"
        cppFlags  += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()
        cppFlags  += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()

        ldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"] //added z
        stl = "stlport_static"//"gnustl_shared" changed to stlport static
    }

    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles += file('proguard-rules.pro')
        }
    }
    android.productFlavors { //added all productFlavors code
        create("arm") {
            ndk.with {
                abiFilters += "armeabi"
                File curDir = file('./')
                curDir = file(curDir.absolutePath)
                String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi\" //"-L" +
                ldLibs += libsDir + "libnative_camera_r4.3.0.so"
                ldLibs += libsDir + "libopencv_contrib.a"
                ldLibs += libsDir + "libopencv_core.a"
                ldLibs += libsDir + "libopencv_highgui.a"
                ldLibs += libsDir + "libopencv_imgproc.a"
                ldLibs += libsDir + "libopencv_info.so"
                ldLibs += libsDir + "libopencv_java.so"
                ldLibs += libsDir + "libopencv_legacy.a"
                ldLibs += libsDir + "libopencv_ml.a"
                ldLibs += libsDir + "libopencv_ts.a"
            }
        }
        create("armv7") {
            ndk.with {
                abiFilters += "armeabi-v7a"
                File curDir = file('./')
                curDir = file(curDir.absolutePath)
                String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi-v7a\" //"-L" +

               ldLibs += libsDir + "libnative_camera_r4.3.0.so"
               ldLibs += libsDir + "libopencv_contrib.a"
               ldLibs += libsDir + "libopencv_core.a"
               ldLibs += libsDir + "libopencv_highgui.a"
               ldLibs += libsDir + "libopencv_imgproc.a"
               ldLibs += libsDir + "libopencv_info.so"
               ldLibs += libsDir + "libopencv_java.so"
               ldLibs += libsDir + "libopencv_legacy.a"
               ldLibs += libsDir + "libopencv_ml.a"
               ldLibs += libsDir + "libopencv_ts.a"
            }
         }
         create("fat") {
         }
     }
    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        compile 'com.android.support:appcompat-v7:23.0.0'
        compile project(':openCVLibrary2411')
    }

With this changes I can call my native dummy function in c++ file under jni folder. Also #include <opencv2/core/core.hpp> and others are supported by CLion... When I declare cv::Mat mat; gives me this error:

Linker failed while linking libmymodule.so failed.
C:DevAndroidOpenCV-android-sdksdk
ativejniinclude/opencv2/core/mat.hpp:278: error: undefined reference to 'cv::fastFree(void*)'
C:DevAndroidOpenCV-android-sdksdk
ativejniinclude/opencv2/core/mat.hpp:367: error: undefined reference to 'cv::Mat::deallocate()'
collect2.exe: error: ld returned 1 exit status

c++ code:

#include <jni.h>
#include <vector>
#include <string>
#include "helpers.h"
#include <opencv2/core/core.hpp> //This is supported by CLion
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;

extern "C" {
JNIEXPORT jstring JNICALL
Java_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass type) {
    cv::Mat mat; //causing error

    string s = "Cpp v1 - succ ";
    return env->NewStringUTF(s.data());
}

}

Update

- added "z" to ldLibs
- added android.productFlavors block

Now compilation is successfull, application starts for second and then crashes with this messages
Event log:

IllegalArgumentException: Error while starting native debug session: Unable to find process for android.overloaded.nativetestv4 on device huawei-huawei_y530_u00-64a6513ccd8e

Debug info:

Restart ADB integration and try again
Waiting for process: android.overloaded.nativetestv4
DEVICE SHELL COMMAND: run-as android.overloaded.nativetestv4 mkdir -p /data/data/android.overloaded.nativetestv4/lldb/bin
DEVICE SHELL COMMAND: cat /data/local/tmp/lldb-server | run-as android.overloaded.nativetestv4 sh -c 'cat > /data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server; chmod 700 /data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server'
DEVICE SHELL COMMAND: rm /data/local/tmp/lldb-server
DEVICE SHELL COMMAND: cat /data/local/tmp/start_lldb_server.sh | run-as android.overloaded.nativetestv4 sh -c 'cat > /data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh; chmod 700 /data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh'
DEVICE SHELL COMMAND: rm /data/local/tmp/start_lldb_server.sh
Now Launching Native Debug Session
Error while starting native debug session: java.lang.IllegalArgumentException: Unable to find process for android.overloaded.nativetestv4 on device huawei-huawei_y530_u00-64a6513ccd8e

log:

A/libc﹕ Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 3077 (ed.nativetestv4)

解决方案

After few weeks of pain, I succed. Here is my correct code for Android studio 1.3.1, OpenCv 2.4.11. First you should do this OpenCV in Android Studio (don't use paths which contains white space, both for project and opencv extraction folder) then, for opencv to be native:

gradle-wrapper.properties:

distributionUrl=https://services.gradle.org/distributions/gradle-2.5-all.zip 

build.gradle(application):

classpath 'com.android.tools.build:gradle-experimental:0.2.0'

build.gradle(module):

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.0"

        defaultConfig.with {
            applicationId = "android.overloaded.nativetestv4"
            minSdkVersion.apiLevel = 18
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }
    }


    android.ndk{
        moduleName = "mymodule"
        ldLibs += ['log']
        cppFlags += "-std=c++11"
        cppFlags += "-fexceptions"
        cppFlags  += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()
        cppFlags  += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()



//        ldFlags += linkOpt
        ldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"]// , "ibopencv_core"
        stl = "gnustl_shared"//"gnustl_static"//"gnustl_shared"//"stlport_static"
    }

    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles += file('proguard-rules.pro')
        }
    }

    android.productFlavors {
        create("arm") {
            ndk.with {
                abiFilters += "armeabi"

                File curDir = file('./')
                curDir = file(curDir.absolutePath)
                String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi\" //"-L" +

                ldLibs += libsDir + "libnative_camera_r4.3.0.so"
                ldLibs += libsDir + "libopencv_contrib.a"
                ldLibs += libsDir + "libopencv_core.a"
                ldLibs += libsDir + "libopencv_highgui.a"
                ldLibs += libsDir + "libopencv_imgproc.a"
                ldLibs += libsDir + "libopencv_info.so"
                ldLibs += libsDir + "libopencv_java.so"
                ldLibs += libsDir + "libopencv_legacy.a"
                ldLibs += libsDir + "libopencv_ml.a"
                ldLibs += libsDir + "libopencv_ts.a"

            }
        }
        create("armv7") {
            ndk.with {
                abiFilters += "armeabi-v7a"

                File curDir = file('./')
                curDir = file(curDir.absolutePath)
                String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi-v7a\" //"-L" +

                ldLibs += libsDir + "libnative_camera_r4.3.0.so"
                ldLibs += libsDir + "libopencv_contrib.a"
                ldLibs += libsDir + "libopencv_core.a"
                ldLibs += libsDir + "libopencv_highgui.a"
                ldLibs += libsDir + "libopencv_imgproc.a"
                ldLibs += libsDir + "libopencv_info.so"
                ldLibs += libsDir + "libopencv_java.so"
                ldLibs += libsDir + "libopencv_legacy.a"
                ldLibs += libsDir + "libopencv_ml.a"
                ldLibs += libsDir + "libopencv_ts.a"

            }
        }
        create("x86") {
            ndk.with {
                abiFilters += "x86"
            }
        }
        create("mips") {
            ndk.with {
                abiFilters += "mips"
            }
        }
        create("fat") {

        }
    }

}
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:23.0.0'
    compile project(':openCVLibrary2411')
}

.cpp

#include <jni.h>
#include <vector>
#include <string>
#include "helpers.h"
#include <opencv2/core/core.hpp>

using namespace std;

#ifdef __cplusplus
extern "C" {
#endif



JNIEXPORT jstring JNICALL
Java_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass type) {

    cv::Mat mat(33,22, 1);

    string s = "Cpp v1 - succ, rows#:" + Helpers::ToStringNum(mat.rows);
    Helpers::Log(s);

    return env->NewStringUTF(s.data());
}

}

.java

package android.overloaded.nativetestv4;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity
{
    static {
        System.loadLibrary("mymodule");
    }

    public static native String FuncV1();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toast.makeText(this, FuncV1(), Toast.LENGTH_LONG).show();

        ((TextView)findViewById(R.id.txtInfo)).setText(FuncV1());
    }

Update for Android Studio 1.5.1, OpenCV 3.1
1. First you should do this OpenCV in Android Studio (don't use paths which contains white space, both for project and opencv extraction folder), after that you should have normal working Java app
2. Change build.gradle in project root:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle-experimental:0.4.0"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

  1. Change gradle-wrapper.properties:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-2.8-all.zip

  1. Change build.gradle in opencv module:

    apply plugin: 'com.android.model.library'
    
    model {
        android {
            compileSdkVersion = 23
            buildToolsVersion = "23.0.2"
            defaultConfig.with {
                minSdkVersion.apiLevel = 11
                targetSdkVersion.apiLevel = 23
            }
    
    
        }
    
        android.buildTypes {
            release {
                minifyEnabled = false
                proguardFiles.add(file("proguard-rules.txt"))
            }
        }
    }
    

  2. Change build.gradle in app module:

    apply plugin: 'com.android.model.application'
    
    model {
        android {
            compileSdkVersion = 23
            buildToolsVersion = "23.0.2"
    
            defaultConfig.with {
                applicationId = "android.overloaded.opencv31v1" //Name of package
                minSdkVersion.apiLevel = 11
                targetSdkVersion.apiLevel = 23
                versionCode = 1
                versionName = "1.0"
    
            }
        }
    
        android.ndk {
            moduleName = "native" // Name of C++ module, for System.loadLibrary("native")
            cppFlags.add("-std=c++11") // Add provisions to allow C++11 functionality
            cppFlags.add("-fexceptions")
            // YOUR OPENCV DIRECTORY!!!
            cppFlags.add("-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()) 
            ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "z"])
            stl = "gnustl_shared"
        }
    
        android.buildTypes {
            release {
                minifyEnabled = false
                proguardFiles.add(file("proguard-rules.txt"))
            }
        }
    
        android.productFlavors {
            create("arm") {
                ndk.with{
                    abiFilters.add("armeabi")
    
                    File curDir = file('./')
                    curDir = file(curDir.absolutePath)
                    String libsDir = curDir.absolutePath + "\src\main\jniLibs\armeabi\"
    
                    ldLibs.add(libsDir + "libopencv_core.a")
                    ldLibs.add(libsDir + "libopencv_highgui.a")
                    ldLibs.add(libsDir + "libopencv_imgproc.a")
                    ldLibs.add(libsDir + "libopencv_java3.so")
                    ldLibs.add(libsDir + "libopencv_ml.a")
    
                }
            }
            create("armv7") {
                ndk.with {
                    abiFilters.add("armeabi-v7a")
    
                    File curDir = file('./')
                    curDir = file(curDir.absolutePath)
                    String libsDir = curDir.absolutePath + "\src\main\jniLibs\armeabi-v7a\"
                    ldLibs.add(libsDir + "libopencv_core.a")
                    ldLibs.add(libsDir + "libopencv_highgui.a")
                    ldLibs.add(libsDir + "libopencv_imgproc.a")
                    ldLibs.add(libsDir + "libopencv_java3.so")
                    ldLibs.add(libsDir + "libopencv_ml.a")
                    ldLibs.add(libsDir + "libopencv_ts.a")
    
                }
            }
        }
        android.sources{
            main{
                jni{
                    source{
                        srcDirs += ['src/main/jniMy']
                    }
                }
            }
        }
    }
    dependencies {
        compile fileTree(dir: "libs", include: [$/*.jar/$])
        compile "com.android.support:appcompat-v7:23.1.1" //Do not use 23.2.0 
        compile project(":openCVLibrary310")
    }
    

  3. Create dir app/src/main/jniMy, this is place for yours .cpp files

  4. Optionally create file chelper.c in jniMy, with this code:

    #ifndef OPENCV31V1_CHELPER_H
    #define OPENCV31V1_CHELPER_H
    
    #include <jni.h>
    #include <vector>
    #include <string>
    #include <sstream>
    #include <android/log.h>
    
    using namespace std;
    
    class Helpers{
    public:
        template <typename T>
        static string ToStringNum(T tNumber){
            ostringstream ostrStream;
            ostrStream << tNumber;
            return ostrStream.str();
        }
    
        static void Log(string s){
            __android_log_print(ANDROID_LOG_INFO, "My", s.data());
        }
        static void Log(std::exception ee){
            string s = "Exception: " + string(ee.what()) ;
            __android_log_print(ANDROID_LOG_INFO, "My", s.data());
        }
    
        static long Time(){
            struct timespec now;
            clock_gettime(CLOCK_MONOTONIC, &now);
            return (long)((int64_t)now.tv_sec * 1000LL + now.tv_nsec /1000000LL);
        }
        static string Time(long iTime){
            return ToStringNum(Time() - iTime) + "ms";
        }
    
    };
    #endif //OPENCV31V1_CHELPER_H
    

  5. Create file native_exporter.cpp in jniMy, with this code:

    #include <jni.h>
    #include <string>
    #include <opencv2/core/core.hpp>
    #include "chelper.h"
    
    extern "C"{
    JNIEXPORT jstring     JNICALLJava_android_overloaded_opencv31v1_MainActivity_FuncV1(JNIEnv *env,
    jclass type) {
    
        cv::Mat mat(33,22, CV_32FC2);
    
        string s = "Cpp v1 - succ, rows#:" +Helpers::ToStringNum(mat.rows);
        Helpers::Log(s);
        auto i = 5;
        for (int i2 : {1,3,5}){
            Helpers::Log(Helpers::ToStringNum(i2));
        }
    
        return env->NewStringUTF(s.data());
    }
    }
    

  6. Code in MainActivity.java:

    package android.overloaded.opencv31v1;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.SurfaceView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import org.opencv.android.CameraBridgeViewBase;
    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    
    public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2
    {
        private static void Log(String sMsg){Log.i("My", "MainActivity." + sMsg );}
    
        static{
            System.loadLibrary("opencv_java3");
            System.loadLibrary("native");
        }
    
        public native String FuncV1();
        JavaCameraViewCustom2 _javaCameraView; //Similar to JavaCameraView
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            if(getSupportActionBar() != null)getSupportActionBar().hide();
            String sRes = FuncV1();
            Toast.makeText(this, sRes, Toast.LENGTH_LONG).show();
    
            ((TextView)findViewById(R.id.txtInfo)).setText(sRes);
    
            _javaCameraView = (JavaCameraViewCustom2)findViewById(R.id.cameraView);
            _javaCameraView.setVisibility(SurfaceView.VISIBLE);
            _javaCameraView.setCvCameraViewListener(this);
    
        }
    
        @Override
        protected void onResume()
        {
            super.onResume();
            _javaCameraView.enableView();
        }
    
        @Override
        protected void onPause()
        {
            super.onPause();
            _javaCameraView.disableView();
        }
    
        Mat _imgBgrTemp;
        @Override
        public void onCameraViewStarted(int width, int height)
        {
            _imgBgrTemp = new Mat(height,width, CvType.CV_8UC4);
        }
    
        @Override
        public void onCameraViewStopped()
        {
            _imgBgrTemp.release();
        }
    
        @Override
        public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame)
        {
            _imgBgrTemp = inputFrame.rgba();
            return _imgBgrTemp;
        }
    }  
    

Android Studio will ask you to change jdk, also it will install new gradle, you should do everything it ask.

这篇关于OpenCv with Android studio 1.3+ using new gradle - undefined reference的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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