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
就可以输入密码了。