当前位置导航:炫浪网>>网络学院>>编程开发>>JAVA教程>>J2EE

JNI调用C/C++方法从控制台输入密码

最近看到一个问题,如何用Java实现从控制台输入密码?
    本来以为是很简单的问题,查了一下发现Java居然没提供这样一个方法。目前实现的方式有2个,一个是利用JNI来调用C/C++方法,另一个是使用多线程。
下面是使用JNI的方法:
首先,写出我们的Java类:


public   class  JNIPasswordReader  {

     private   native  String readPassword();
     static {
        System.loadLibrary( " PasswordDLL " );
    }
     /** */ /**
     *  @param  args
      */
     public   static   void  main(String[] args)  {
         //  TODO Auto-generated method stub
        JNIPasswordReader reader  =   new  JNIPasswordReader();
        String pwd  =  reader.readPassword();
        System.out.println( " \nYour Password is: "   +  pwd);
    }

}

    这一段使用System.loadLiberary("..");来加载本地类库,PasswordDLL是文件名,不需要加dll后缀,系统会自动辨认。

编译成JNIPasswordReader.class以后,使用
javah -jni JNIPasswordReader
命令,生成一个JNIPasswordReader.h文件,文件内容如下:

/**/ /*  DO NOT EDIT THIS FILE - it is machine generated  */
#include  < jni.h >
/**/ /*  Header for class JNIPasswordReader  */

#ifndef _Included_JNIPasswordReader
#define  _Included_JNIPasswordReader
#ifdef __cplusplus
extern   " C "   {
#endif
/**/ /*
 * Class:     JNIPasswordReader
 * Method:    readPassword
 * Signature: ()Ljava/lang/String;
  */
JNIEXPORT jstring JNICALL Java_JNIPasswordReader_readPassword
  (JNIEnv  * , jobject);

#ifdef __cplusplus
}
#endif
#endif

然后,我们需要写一个cpp文件来实现
JNIEXPORT jstring JNICALL Java_JNIPasswordReader_readPassword  (JNIEnv *, jobject);
接口。
于是,我写了一个PasswordDLL.cpp文件,内容如下:

//  这是主 DLL 文件。
#include  " stdafx.h "
#include  " JNIPasswordReader.h "
#include  < iostream >
#include  < iomanip >
#include  < conio.h >
using   namespace  std;

/**/ /*
 * Class:     JNIPasswordReader
 * Method:    readPassword
 * Signature: ()V
  */
JNIEXPORT jstring JNICALL Java_JNIPasswordReader_readPassword
  (JNIEnv  *  env, jobject) {
       char  str[ 20 ]  =   { 0 } ; 
    jstring jstr;
     char  ch;
     char   * pstr  =  str;
     while ( true )
     {
        ch  =  getch();
         if (isdigit(ch) || isalpha(ch))
         {
            cout << " * " ;
             * pstr ++   =  ch;
        }
         else   if (ch  ==   ' \b '   &&  pstr  >  str)
         {
             * ( -- pstr)  =   0 ;
            cout << " \b \b " ;
        }
         else   if (ch  ==   0x0A   ||  ch  ==   0x0D )
         {
             break ;
        }
    }
    jstr  =  env -> NewStringUTF(str);
     return  jstr;
}

    我使用VS2005来生成对应的dll文件,在生成之前,需要把$JDK_HOME/include/jni.h和$JDK_HOME/include/win32/jni_md.h这两个文件copy到Microsoft Visio Studio 8/VC/include目录下,我就在这里卡了大概1个小时,一直说找不到jni.h文件

   然后就可以使用VS2005来生成dll了,生成好对应的PasswordDLL.dll以后,把该dll文件放到系统变量PATH能找到的地方,比如windows/system32/或者jdk/bin目录,我是放到JDK_HOME/bin下面了
放好以后,
执行java JNIPasswordReader
就可以输入密码了。

关于JNI的更详细内容,可以参考:
《在Windows中实现Java本地方法》http://www.ibm.com/developerworks/cn/java/jnimthds/index.html

我的Password.dll文件
http://www.blogjava.net/Files/richardeee/PasswordDLL.zip

相关内容
赞助商链接