首先,在eclipse里建立新的java project。新建包com.cogito。之后新建类TestNative,之后配置Opencv3(详见上一篇博客),代码如下。
注意:声明的public native开头的函数就是你要从.dll中获取的函数。
package com.cogito;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
public class TestNative {
public native void sayHello();
public native void test01(String g);
public static void main(String[] args) {
System.loadLibrary("ConsoleApplication2"); //载入dll库 //注意!不要写.dll
String g;
g="girl.jpg";
TestNative test = new TestNative();
test.sayHello(); //调用本地方法</span>
test.test01(g);
}
}
之后到这个项目文件目录里-bin,在bin的文件夹下按shift右键,进入cmd,输入javah com.cogito.TestNative
,点击enter,之后会发现bin文件夹多了一个com_cogito_TestNative.h。
之后进入vs2015,新建一个.dll文件。之后将你刚刚生成的com_cogito_TestNative.h复制到这个项目文件里,之后将你的java的jdk的文件夹打开,找到目录jdk1.7.0_80\include下的文件jni.h和jdk1.7.0_80\include\win32下的文件jnimd.h将jni和jnimd两个文件也复制到刚刚建立的.dll文件夹里。之后再次打开.dll文件,文件是下图所示
之后配置vs2015的opevcv3(详见上节)
之后source.cpp里可以加入想要实现的内容,例子:我的.dll文件的名字为:ConsoleApplication2
ConsoleApplication2里的com_cogito_TestNative.h和source.cpp代码如下:
//com_cogito_TestNative.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class com_cogito_TestNative */
#ifndef _Included_com_cogito_TestNative
#define _Included_com_cogito_TestNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_cogito_TestNative
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_cogito_TestNative_sayHello
(JNIEnv *, jobject);
/*
* Class: com_cogito_TestNative
* Method: test01
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_cogito_TestNative_test01
(JNIEnv *env, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
//source.cpp
# include "com_cogito_TestNative.h"
# include <iostream>
using namespace std;
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
JNIEXPORT void JNICALL Java_com_cogito_TestNative_sayHello(JNIEnv *, jobject)
{
cout << "Hello World!" << endl;
}
JNIEXPORT void JNICALL Java_com_cogito_TestNative_test01(JNIEnv *env, jobject, jstring g)
{
const char* str;
str = env->GetStringUTFChars(g, false); //这是将jstring 转成c++能读懂的char*
if (str == NULL) {
cout << "error!!!!!!!!!!!!!" << endl; /* OutOfMemoryError already thrown */
}
std::cout << str << std::endl;
Mat girl = imread(str); //载入图像到Mat
namedWindow("【1】动漫图"); //创建一个名为 "【1】动漫图"的窗口
imshow("【1】动漫图", girl);//显示名为 "【1】动漫图"的窗口
waitKey();
}
之后重新生成.dll项目,在”输出“中会出现.dll的生成路径,到路径中去找你得.dll
之后到java项目中
JNI编程之如何传递参数——String参数的传递
- #include"Prompt.h"
- #include<iostream>
- JNIEXPORT jstringJNICALL Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
- {
- const char* str;
- str = env->GetStringUTFChars(prompt, false);
- if(str == NULL) {
- return NULL; /* OutOfMemoryError already thrown */
- }
- std::cout << str << std::endl;
- env->ReleaseStringUTFChars(prompt, str);
- char* tmpstr = "return string succeeded";
- jstring rtstr = env->NewStringUTF(tmpstr);
- return rtstr;
- }
在上面的例子中,作为参数的prompt不能直接被C++程序使用,先做了如下转换
str = env->GetStringUTFChars(prompt, false);
将jstring类型变成一个char*类型。
返回的时候,要生成一个jstring类型的对象,也必须通过如下命令,
jstring rtstr = env->NewStringUTF(tmpstr);
这里用到的GetStringUTFChars和NewStringUTF都是JNI提供的处理String类型的函数,还有其他的函数这里就不一一列举了。