一、java JNI 調用動態庫
1、在MyEclipse 中創建一個test的web工程
2、在工程下創建一個class文件 package名爲JNI ,類名test
3、在test下面定義一個方法
package JNI;
public class getCPUID {
//定義一個方法 該方法是在dll中實現
public native static String getcpuID();
static
{
System.loadLibrary( "getCPUID" ); //加載dll庫
}
}
4、發佈該web 程序(目的是把test類編譯成class文件,你也可以直接用編譯工具編譯該clss文件)
5、 將在發佈後的文件中找到該 JNI文件夾 ,複製該文件夾所在路徑(發佈的是放在resin)
D:\yys\resin-pro-3.1.7a\deploy\test2\WEB-INF\classes\JNI
6、打開dos命令行 輸入cd D:\yys\resin-pro-3.1.7a\deploy\test2\WEB-INF\classes\
(如果cd 目錄沒變,那在後面在 輸入 d: 回車 一般不會出先這種問題 ,但是我很幸運的 遇到了)
7、javah JNI.getCPUID 此時生成JNI_getCPUID.h頭文件
8、創建一個空的win32 dll項目 ,我這用的是vs2008 visual c++ win32項目 空項目 名稱
getCPUID(注 這個要與System.loadLibrary( "getCPUID" ); //加載dll庫中名稱一致)
9、分別把java安裝路徑下 C:\Program Files\Java\jdk1.5.0_06\include 文件夾中的 jni.h 與
C:\Program Files\Java\jdk1.5.0_06\include\win32 jin_md.h 及先前生成的JNI_getCPUID.h
拷貝到c++項目的工程目錄下。
10、把剛拷貝過來的頭文件添加到項目的頭文件夾中
11、創建一個 getCPUID.cpp文件 在該文件添加如下代碼
#include "JNI_getCPUID.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//彙編獲取 cpu編號
int getCPUID(char * cpuid)
{
unsigned long s1,s2,s3,s4;
unsigned long s11,s22,s33,s44;
char p1[128]; char p2[128]; char p3[128]; char p4[128];
unsigned int eax = 0;
unsigned int ebx,ecx,edx;
__asm
{
mov eax, 1;
cpuid ;
mov s1, eax
mov s2, ebx
mov s3, ecx
mov s4, edx
}
s11=s1; s22=s2; s33=s3; s44=s4;
//這裏猶豫cpu 真實的序列號在p4之後就被禁止使用只能取到第32 processorID
sprintf(cpuid, "%08X%08X", s44,s11);
return 0;
}
//char 轉 jstring
jstring stoJstring(JNIEnv* env, char* pat)
{
jclass strClass = env->FindClass("Ljava/lang/String;");
jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(pat));
env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
jstring encoding = env->NewStringUTF("utf-8");
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
}
//數據類型轉換
JNIEXPORT jstring JNICALL Java_JNI_getCPUID_getcpuID
(JNIEnv * env, jclass js)
{
char cpuid[40];
getCPUID(cpuid);
return stoJstring(env,cpuid);
}
12、修改JNI_getCPUID.h 文件的<jni.h> 把<>改爲“” 否則 會包找不到頭文件錯誤。
13、編譯項目把生成的 getCPUID.dll 拷貝到任何一個換件變量path 路勁下就可以 我這拷貝到
C:\Program Files\Java\jdk1.5.0_06\bin 文件夾下
14、做個一個是測試的jsp頁面 或者 在上面的java文件的類後面 加一個 main方法進行測試 加完mian如下
package JNI;
public class getCPUID {
//定義一個方法 該方法是在dll中實現
public native static String getcpuID();
static
{
System.loadLibrary( "getCPUID" ); //加載dll庫
}
public static void main(String[] args) {
//yysLic u=new yysLic();
@SuppressWarnings("unused")
String ls_cpuID=getCPUID.getcpuID();
}
}
調試 查看 ls_cpuID 變量的值
15、在寫jni代碼是常用的 java與c++類型轉換的 方法(注 int 不需要手動轉能自動轉換)
//char * 轉java的jstring
jstring stoJstring(JNIEnv* env, char* pat)
{
jclass strClass = env->FindClass("Ljava/lang/String;");
jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(pat));
env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
jstring encoding = env->NewStringUTF("utf-8");
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
}
//
//jstring 轉 char*
//jstring to char*
char* jstringTostring(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("utf-8");
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);
return rtn;
}
16、猶豫java不能直接獲取電腦硬件信息通過該方法能獲取到 電腦的信息也能通過該方法對公司的一些核心代碼算法
進行加密 軟件論證等 這都是比較好用 。