java JNI调用动态库 获取硬件信息 制作软件加密


一、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 变量的值 

       java JNI调用动态库 获取硬件信息 制作软件加密_第1张图片

  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不能直接获取电脑硬件信息通过该方法能获取到 电脑的信息也能通过该方法对公司的一些核心代码算法
         进行加密 软件论证等 这都是比较好用   。
 

你可能感兴趣的:(java,jni,硬件,库,软件加密)