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
就可以輸入密碼了。