一、编写Java类
package test;
public class TestJNI
{
public native int add(int a,int b);
public native String upperCase(String str);
static
{
System.loadLibrary("JniDll");
}
public static void main(String[] args)
{
TestJNI test = new TestJNI();
int a=100, b=20, result;
result = test.add(a, b);
System.out.println("sum:" + result);
String str1, str2,str3;
str1 = "abcDEFhijk";
str3 = "eahis";
str2=test.upperCase(str1);
System.out.println(str2);
}
}
二、编译完成后生成TestJNI.class文件
三、执行javah TestJNI命令,生成.h文件
Cmd切换到src目录cd E:\eclipse\workspace\JNI\src
javah -classpath E:\eclipse\workspace\JNI\bin-d d:/ -jni test.TestJNI
产生test_TestJNI.h文件到d:\
在java中,提供了javah这个命令来生成本地方法的头文件。使用命令如下:
javah-classpath A -d B -jni C
其中,A是你的.class文件的路径,这样java就可以搜索到这个.class文件。B是将要生成的头文件的存放目录,可以根据需要指定。C是java类名,在这个例子中就是com.jni.test.Example。然后就可以在B目录下看到生成的头文件了。
6、打开vc++,新建一个DLL程序,选中Empty project,将test_TestJNI.h复制到此工程目录下,并添加到工程中,JniDll.cpp文件,包含jdk相应文件,(工具-选项-目录)Tools-->Options-->vc++ Directories-->include files:D:\ProgramFiles(x86)\Java\jdk1.7.0_02\include
D:\ProgramFiles(x86)\Java\jdk1.7.0_02\include\win32
注意:cpp中的方法名和.h中的方法名,必须完全一致
#include <iostream>
#include <string>
#include <windows.h>
#include "test_TestJNI.h"
using namespace std;
JNIEXPORT jint JNICALL Java_test_TestJNI_add(JNIEnv *env,jobject,jint a,jint b)
{
int result = (int)(a +b);
return (jint)result;
}
jstring str2jstring(JNIEnv *env,const char* pat)
{
//定义java String类strClass
jclass strClass = (env)->FindClass("Ljava/lang/String;");
//获取String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
jmethodID ctorID = (env)->GetMethodID(strClass,"<init>","([BLjava/lang/String;)V");
//建立byte数组
jbyteArray bytes = (env)->NewByteArray(strlen(pat));
//将char*转换为byte数组
(env)->SetByteArrayRegion(bytes, 0,strlen(pat), (jbyte*)pat);
// 设置String, 保存语言类型,用于byte数组转换至String时的参数
jstring encoding = (env)->NewStringUTF("GB2312");
//将byte数组转换为java String,并输出
return (jstring)(env)->NewObject(strClass,ctorID,bytes,encoding);
}
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);
string stemp(rtn);
free(rtn);
return stemp;
}
JNIEXPORT jstring JNICALL Java_test_TestJNI_upperCase(JNIEnv *env,jobject,jstring str)
{
string strUpper;
strUpper =jstring2str(env,str);
strUpper = (string)strupr((char*)strUpper.c_str());
jstring strResult =str2jstring(env,strUpper.c_str());
return strResult;
}
用组件模式release,不可用debug模式,编译和生成dll,复制dll到src目录即可。
JAVA运行结果:
sum:120
ABCDEFHIJK