zoukankan      html  css  js  c++  java
  • Java与C/C++异构平台的本地通信(Java也可以操作硬件) (转)

    Java本身已经足够强大,但是在某些情况下,Java也是有局限的,最大的局限在于不能直接操作硬件,因为Java是运行在JVM上的,不是直接运行于CPU。另一个原因在于相比于C/C++而言,Java的运行效率比较低,但是C/C++虽然运行效率高,且能够直接操作硬件,但是的带来的不足是,开发效率太低,那就将Java与C/C++结合起来吧!利用各自的优势,发挥最大的潜力。

    这里使用的就是JNI技术,Java Native Interface(Java本地接口)

    说起来也很简单,就是用Java定义业务逻辑接口,然后用C/C++是实现这些接口,并且这些实现对于Java的调用是透明的。

    首先创建一个Java项目jnidemo

    如下:

    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog

    定义了一个UserInfo类,和一个UserService业务逻辑对象

    UserInfo类,只有一个id和name成员变量

    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog
     

    UserService业务逻辑类

    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog

    static{}这句话待会儿说

    值得注意的是这里定义了2个方法,countUser和findUserById,但是并没有实现,而且用native标注

    这就说明了这两个方法是本地托管方法,通俗的说就是让C/C++去实现的方法,而Java不必去管怎么实现的。

    好以上就是Java的工程,下面看看C/C++的工程

    采用的IDE是Visual Stdio 2008

    这里比较复杂

    1.第一步,导出刚刚Java托管的UserService业务逻辑类托管的C/C++头文件

    具体做法:开始->运行->cmd

    然后进入到jnidemo的项目的根目录下或者bin目录(Web工程没有bin目录),

    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog

    然后运行 javah -jni com.sean.jni.service.UserService(类的绝对路径)

    然后在bin目录里就能看到生成的C/C++头文件

    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog
     
     
     
    下面开始创建C/C++工程
     
    利用VS创建一个MFC dll工程
    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog
    并且将生成的头文件com_sean_jni_service_UserService.h拷贝到工程中
    还要将jni.h(在%JAVA_HOME%/include目录中)和jni_md.h(在%JAVA_HOME%/include/win32目录中)这两个头文件一起拷贝到工程中
     
     
    然后就要开始写代码了
    创建UserService.cpp文件(也可以.c文件)
    代码如下
    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog
     
    可以看到这里实现了2个方法正是Java托管的接口countUser和findUserById
     
    为了简单起见,在countUser直接返回100,
    而在findUserById方法里,通过java传进来的Id,创建一个UserInfo对象,id = java传进来的Id,name = “Sean”,并返回给Java。
    如果对Java反射比较熟悉的话,可以看到,在C++实现的这部分代码,是不是有点反射的味道?
    恩,这就对了。
     
     
     
     
    好,C/C++的工程就完了,接下来的要做的就是连接Java和C/C++
    编译C/C++工程后,在工程的debug目录中会生成一个dll文件,JNIDemo.dll(具体的文件名是工程的名称)
    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog

    好,要的就是这个dll文件,dynamic link library(动态链接库)

    将这个dll拷贝到java工程中,可以新建一个dll代码文件夹(随意)

    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog
     
     
    然后在UserService这个java类中,添加一句代码
    static {         System.loadLibrary("dll/JNIDemo"); }
     
    没错,就是将这个库导入到java工程中
     
     
     
    到此为止,整个工程就完结了,实现了java调用C/C++,来处理业务逻辑
     
     
     
    下面写个测试函数来看看吧
    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog
    代码很简单
    首先调用countUser方法,统计总共多少人?刚刚在C/C++工程里返回的是100,所以应该打印出100
     
    然后调用findUserById(10000),参数为10000,所以返回来的用户对象,id=10000,name=Sean
     
    为了测试java调用C/C++的效率,这里还统计了调用的时间
     
     
    上面代码的运行情况应该是
    总共人数:100
    the parameter is : 10000
    用户Id:10000
    用户姓名:Sean
    总共花费:xxx毫秒
     
    运行结果
    Java与C/C++异构平台的本地通信(Java也可以操作硬件) - Seans Blog - Seans Blog
     
    运行结果完全正确,而且只用了4毫秒(实际肯定小于4毫秒),虽然速度肯定比不上直接运行C/C++,但是相比Java而言,这个速度还是可以接受的。
     
     
    通过这个案例,我们还可以想的远一点,虽说Java不能直接操作硬件,但是是不是可以让C/C++去操作硬件,然后用Java来直接调用呢?
    答案是完全可以的,这也就说明了,Java和C/C++是可以互相协作开发的。
  • 相关阅读:
    【调侃】IOC前世今生
    经典 makefile 教程
    Win7  CMD大全
    关于验证码识别3
    关于验证码识别2
    关于验证码识别 1
    DirectUI的初步分析-转
    winform软件版本检测自动升级开发流程(转)
    如何让在panel里的子窗体随panel的大小改变而变化?(转)
    C#如何控制panel加载的字窗体中控件的位置随着显示器分辨率大小而改变
  • 原文地址:https://www.cnblogs.com/lonsine/p/2977818.html
Copyright © 2011-2022 走看看