java jni 调用c++ opencv代码成功范例
- java上建立接口定义
package com.dtk; public class Rec { public native String RecImage(String src); public static void main(String[] args) { } }
- 生成头文件:
cmd进入java类生成的class所在目录,一般是bin, 使用命令格式 [javah 包名.文件名], eg: javah com.dtk.Rec, 生成了com_dtk_Rec.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_dtk_Rec */ #ifndef _Included_com_dtk_Rec #define _Included_com_dtk_Rec #ifdef __cplusplus extern "C" { #endif /* * Class: com_dtk_Rec * Method: RecImage * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_dtk_Rec_RecImage(JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif
- 在VS中新建空console项目,引入com_dtk_Rec.h, 注意要配置jni.h等所在的目录,不然会有些undefine,
-
- 写一个cpp实现掉com_dtk_Rec.h中的方法,修改项目生成dll文件,这里可以用opencv等
#include "com_dtk_Rec.h" #include <opencv2/opencv.hpp> using namespace std; using namespace cv; std::string jstring2str(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("GB2312"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); std::string stemp(rtn); free(rtn); return stemp; } // 实现native方法 JNIEXPORT jstring JNICALL Java_com_dtk_Rec_RecImage(JNIEnv *env, jobject, jstring jstr_input) { string imgPath = jstring2str(env, jstr_input); Mat img = imread(imgPath); imshow("img",img); //waitKey(); //destroyAllWindows(); string str = "ABCD"; return env->NewStringUTF(str.c_str()); }
- 这样就可以用java调用了,首先需要加载库,然后进行调用测试,代码如下:
-
package com.dtk; public class Rec { public native String RecImage(String src); static { System.load("D:/XieXiaoWen/VS-Pro/JniRecDll/bin/JniRecDll.dll"); } public static void main(String[] args) { long startTime = System.currentTimeMillis(); // 获取开始时间 Rec nativeCode = new Rec(); String result = nativeCode.RecImage("C:/lena.jpg"); System.out.println(result); System.out.println("JNI成功调用dll!!!"); long endTime = System.currentTimeMillis(); // 获取结束时间 System.out.println("程序运行时间: " + (endTime - startTime) + "ms"); } }
完成