OpenCv与Android studio 1.3+使用new gradle - undefined reference

时间:2015-08-23 20:35:11

标签: opencv android-studio android-ndk android-gradle opencv4android

我在Android Studio 1.3+上使用原生OpenCv 2.4.11(3.0.0也没问题)时遇到了麻烦,并且支持新的ndk。关于.mk文件的所有教程,但我想将它与新的实验gradle一起使用 使用Kiran回答OpenCV in Android Studio 我在java中工作得很好。我也改变了
gradle-wrapper.properties:

    Student

的build.gradle(应用):

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



的build.gradle(模块):

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

通过这些更改,我可以在jni文件夹下的c ++文件中调用我的本机虚拟函数。 CLION也支持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') } 和其他人......当我宣布cv :: Mat mat;给我这个错误:

#include <opencv2/core/core.hpp>

c ++代码:

Linker failed while linking libmymodule.so failed.
C:\DevAndroid\OpenCV-android-sdk\sdk\native\jni\include/opencv2/core/mat.hpp:278: error: undefined reference to 'cv::fastFree(void*)'
C:\DevAndroid\OpenCV-android-sdk\sdk\native\jni\include/opencv2/core/mat.hpp:367: error: undefined reference to 'cv::Mat::deallocate()'
collect2.exe: error: ld returned 1 exit status

更新

- 添加&#34; z&#34;到ldLibs
- 添加了android.productFlavors块

现在编译成功了,应用程序启动了第二个,然后崩溃了这个消息
事件日志:

#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());
}

}

调试信息:

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

日志:

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

1 个答案:

答案 0 :(得分:20)

经过几周的疼痛,我成功了。这是我的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(应用):

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

的build.gradle(模块):

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());
    }

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

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. 更改gradle-wrapper.properties:
  2. 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. 在opencv模块中更改build.gradle:

      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. 在app模块中更改build.gradle:

      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. 创建dir app / src / main / jniMy,这是你的.cpp文件的地方

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

      #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. 使用以下代码在jniMy中创建文件native_exporter.cpp:

      #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. 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;
          }
      }  
      
    7. Android Studio会要求你更改jdk,它也会安装新的gradle,你应该做它所要求的一切。