JNI基础java、C++交互

 老大让做一个用于前台页面调用硬件设备的程序,因为是java公司,第一个想到便是Applet,由它做为前台页面程序。
          最简单的applet
         那么,先做一个applet Demo.本人不懂这个,一开始以为又会是一番艰辛,不过接触之后,再一次被java的强大所感动,太简单了,做完了一点成就感都没有。下面是java代码:
        
class nHello extends {
 public void paint(Graphics g){
     g.drawString("Hello Applet",50,50);
 }   
}

 
        很犀利吧,很难相信这点代码就可以做到什么,但它就是做到了。 现在把它嵌到网页就好了,HTML代码:
 
<html>
    <body>
        <applet id="applet" code="nHello.class" width="500" height="300"/>
    </body>
</html>

 然后把html和class放在同一目录下,浏览器打开,根据你的安全设置,会有不同提示,一般IE默认会提示是不安装Activex控件,同意即可,Firefox则没有提示,直接就运行了.
 
applet和JavaScript合体

 js调用applet是比较简单的,只要是java的publice方法,js都可以直接调用。js代码如下:

var applet = document.getElementById("applet");
applet.hello();



 java代码如下:

public void hello(){
    System.out.println("Hello java");   
}
  
其实Javascript和Applet交互就这么简单(注意,这里是JavaScript调用Applet,不是Applet调用JS.关于Applet中调用JS,可自己搜索相关资料).

如果hello()有返回值的话,JS还可以接受返回值。

最简单的JNI
牛逼的技术出来了,那就是JNI!这个其实也只是技术本身很牛逼,做起来还是很简单,下面在原有的java代码上添加一段:

 static{
    System.loadLiberary("nHello");
  }
  public native void hello();
 


Java要做的就这么多,具体的实现就交给C++了(我用的是VC6.0)


第一步生成class文件 javac nHello.java


第二部生成C++引用的头文件javah nHello.java 生成文件内容如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class nHello */
#ifndef _Included_nHello
#define _Included_nHello
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     nHello
 * Method:    hello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_nHello_hello
  (JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
 
 

这里我们只关心那个方法,把方法copy到下面的c++source file里面

第三部具体的C++代码实现.


新建dll工程->新建c++ source file,下面是实现代码:

#include <stdio.h>
#include <jni.h>
#include <nHello.h>
//从Hello.h拷贝来的
JNIEXPORT void JNICALL Java_nHello_hello
  (JNIEnv *, jobject){
printf("Hello C++");
}
 
不用怀疑c++代码就这么简单,但是jni.h和Hello.h的路径要设置正确,编译器才能找到这两个文件


jni.h在jdk/include下


jni.h里面还会包含一个jni_md.h,在jdk/include/win32目录下


nHello.h就随便你放了


把以上提到的路径加到C++的库目录下.工具->选项->目录.


然后编译dll,就会生成我们需要的dll文件.


这个dll的文件名,就是我们在java代码中System.loadLiberary("nHello")里面的这个参数,大小写无所谓,后缀名不需要,会自动识别。


System.loadLiberary()这个方法会默认搜索几个目录,把dll放在正确的目录下,JVM就能自动加载了.然后我们的native就能运行了。


java nHello,控制台输入


Hello C++;


Applet和JNI合体


上面我们的JNI是没有在applet环境下运行的,下面就要把Applet和JNI结合起来了。


java代码

import java.awt.*;
import java.applet.*;
public class nHello extends Applet{
    public void init(){
        System.loadLibrary("nHello"); 
    }
    
    public static native String hello();
    
    public String nHello(){
        return "Hello,Java "+hello();
    }
}
 
 C++代码


 
#include <stdio.h>
#include "nHello.h"
JNIEXPORT jstring JNICALL Java_nHello_hello
  (JNIEnv *jenv, jobject jobj)
{
    return jenv->NewStringUTF("Hello,C++");
}
Java Script代码

var applet = document.getElementById("applet");
alert("Hello,JavaScript "+applet.nHello());

这里几个主要的代码就这样,至于其他次要的工作,就不再一一赘述.

到了这里我们发现,由于Applet是在客户端运行的,那么我们如何把我们的dll也放到客户端呢.


首先,试试把class文件和dll打包一起发到客户端行不行呢,jar -cvf nHello.jar *.class *.dll.注意,打包的话<applet>标签里面就要加个archive属性,archive="nHello.jar".


打开浏览器,结果失败了,同志们就不要再试了。


那么最简单的方法,就是手动拷贝到客户端,把我们的dll拷贝到system32下.也可以放入服务器bin目录下,据说可以自动跟着applet下载安装,没试过,不清楚。


再打开浏览器运行,如果前面步骤都没问题的话,浏览器应该会报access denied错误.紧要关头,突现离奇错误,为虾米呢?请听下文分解.


applet数字签名


其实动动脚指头就能想得通了,为了安全,applet不可能具有肆无忌惮的权限,想读就读,想写就写,那样网络世界就乱套了。applet默认的安全机制是阻止对客户端的任何操作的(必须阻止).那我们就要想办法允许applet有读写权限。又接着去网上查了许多资料,发现有的人说可以读写,有的人说不能(我的心凉了一半啊,都进行到这一步了,我容易吗我),但是不管怎样,只要还有希望,就要继续努力.按照网友们给出的方法,对applet的jar包签名.


首先把.class都打成jar包:jar -cvf nHello.jar *.class


然后用jdk/bin目录下的keytool生成.store文件:keytool -genkey -keystore nHello.store -alias Mission -validity 999.这样会提示你输入一些信息,最后时候确认即可.


最后用jdk/bin下的jarsigner给jar文件签名 jarsigner -verbose -keystore nHello.store iccard.jar Mission.会提示你输入密码,然后会打印出签名的过程(verbose参数的作用).


关于applet签名的过程,可以去百度“applet签名”,由于以上只凭记忆写的,所以难免有不准的地方。


好了,这下我们的jar包可厉害了,它已经不是一般的jar包了,它是一个签过名的jar包,一个具有对客户端读写权限的jar包.好了,现在让我们满怀期待的打开浏览器,嗯,IE提示是否允许Active,允许,然后就跳出窗口让我们验证签名,允许。。然后,OMG,顺利执行了,然后,然后就没有然后了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值