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

时间: 2024-08-03 05:54:05

JNI调用C/C++方法从控制台输入密码的相关文章

jni- cocos2d中函数通过JNI调用android中类方法的疑问

问题描述 cocos2d中函数通过JNI调用android中类方法的疑问 如题,我试图在cocos2d中调用android的某方法,android中被调用方法如下: public class AppActivity extends Cocos2dxActivity { static { System.loadLibrary("cocos2dcpp"); } public static void gotoActivity() { Intent in = new Intent(AppAct

Linux下JNI调用简单实例操作全过程

开发环境:Linux(Ubuntu 11.04) + JDK 7 实例说明:利用JNI调用本地代码的方法来实现一个计算Int数组总和的功能 使用JNI调用本地代码,整个开发流程主要包括以下几个步骤: 1.创建一个Java类(IntArray.java): 2.使用javac编译该类(生成IntArray.class): 3.使用javah -jni 产生头文件(生成IntArray.h); 4.使用本地代码实现头文件中定义的方法(编写IntArray.c); 5.编译生成本地动态库(生成libI

Java通过JNI调用C语言的方法

JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能. 解决JAVA对本地操作的一种方法就是JNI. JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式).通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法. 简单介绍及应用如下: 一.JAVA中所需要做的工作 在JAVA程序中,首先需要在类中声明所调

python实现在控制台输入密码不显示的方法

  本文实例讲述了python实现在控制台输入密码不显示的方法.分享给大家供大家参考.具体实现方法如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import console; namespace console{ //控制台读取密码,并显示星号 getPassword = function(){ var tstr = {}; var input = kbRead(true); while( inpu

Python实现控制台输入密码的方法

  本文实例讲述了Python实现控制台输入密码的方法.分享给大家供大家参考.具体如下: 1. raw_input() : ? 1 2 3 4 pwd = raw_input('password: ') print pwd # password: aaa # aaa Note: 最简单的方法,但是不安全 2. getpass.getpass() : ? 1 2 3 4 5 import getpass pwd = getpass.getpass('password: ') print pwd #

android JNI调用SDK底层C方法

问题描述 android JNI调用SDK底层C方法 如题:因为上层没法去找到方法,只有想办法去调底层C的方法,SDK源码make出来的.so库文件可以用来做jni的调用么? 底层.c文件里面没有申明JNI,我需要如何去申明 解决方案 你这几个函数的参数,返回值都比较简单,按照JNI的规则,封装导出一下,然后就可以java来调用了 http://www.cnblogs.com/anyanran/archive/2010/11/22/ndk1.html 解决方案二: http://blog.csd

C#实现在控制台输入密码显示星号的方法_C#教程

在控制台输入的内容C#默认按照字符串进行处理,如果直接让用户一次输入完毕就很难实现 显示星号的功能.但是如果让用户一次只能输入一个字符就,在将用户输入的字符替换为星号就可以实现了! 首先,C#中能让用户按下一个按键的方法就是Console.Readkey(),用户一次只能按下一个按键,其中它的另外一个重载方法是Console.ReadKey(bool b),bool类型的参数用来控制是否在控制台上显示用户按下的按键.那么我们可以传入true参数,使用户按下的按键不显示在控制台上,这样光标始终停留

java怎样可以做到利用JNI调用C++类,而不是C++方法?

问题描述 网上搜的介绍几本都通过JNI是java调用C/C++方法的,是否可以用java调用C/C++类呢?因为我底层接口是写的C++类,类中声明了好多变量,这些变量在类中好多方法中要被使用或赋值,相当于全局变量. 解决方案 解决方案二:基本上:无简易方法.如果你需要C++程序处理一个特定的复杂事物,可以考虑将C++写成纯命令行程序,然后Java用Runtime去执行,也就是进程方式.解决方案三:你觉得这样行不行,我在这个类之上再写个方法,在这个方法内调用类.但是这个方法我要多次调用,并且前一次

通过jni调用OpenCv跟直接调用android版openCv对图片进行简单的变换

看看效果图,如果运行时提示需要安装xxxx.mamager,那么就去现在Opencvforandroid,解压以后安装相应的manager安装包就好了 这就是运行的效果,关于jni的调用就不说了,就看下他改变不同效果图的代码 package com.example.opencvdemo1; import org.opencv.android.BaseLoaderCallback; import org.opencv.android.LoaderCallbackInterface; import