zoukankan      html  css  js  c++  java
  • Java Native Interface调用C++代码

    概述

    Java Native Interface译为Java原生接口,简称JNI。Java并不是完美的,它的不足体现在运行速度要比传统的C++慢上许多,并且无法直接访问到操作系统底层,为此Java提供了JNI实现对于底层访问。说得通俗点,通过JNI可以调用其他程序(本地语言),这个语言要可以和操作系统直接交互(C和C++)

    Native

    native修饰的函数简单的说就是调用一个非Java代码写的接口,并且native这个关键字可以和其他标识符号连用,但唯独abstract除外(无实现体)。

    NativeMain类

    public class NativeMain
    {
        static
        {
            System.load("D:/Hello.dll");
        }
    
        public native static void helloC();
    
        public static void main(String[] args)
        {
            helloC();
        }
    }

    使用javac -d . NativeMain.java编译,得到一个class文件

    使用命令javah -jni nativeDemo.NativeMain此时会在当前文件下产生一个nativeDemo_NativeMain.h文件,这个文件名是由(包名 + 类名)组成,中间用(_)隔开。

    我们打开这个文件看下,一脸懵逼。我们尝试看下能看懂的部分,可以看出helloC()函数,生成的是Java_nativeDemo_NativeMain_helloC(JNIEnv *, jclass)函数,Java的数据类型都会按一定规则映射为本地的数据类型,而这些数据类型都是包含的头文件jni.h里定义的。_cplusplus是自定义宏,表示这是一段cpp的代码,加入extern“C”{和}处理其中的代码,JNIEXPORT可以看做是jni的一个标志,void返回值。

    1.打开VS,新建一个项目,命名为Hello

     2.把我们刚才nativeDemo_NativeMain.h复制到VS的项目下,找到安装java的位置,复制jni.h和jni_md.h放置到VS的hello项目下(右边为jni.h和jni_md位置,lz安装位置)

    3.右键头文件>添加>现有项,添加我们刚才复制的三个头文件。

    4.右键源文件>添加>新建项,选择.cpp文件,叫做hello.cpp,实现一个弹出窗口。

    #include "stdafx.h"
    
    #include <iostream>
    
    #include "nativeDemo_NativeMain.h"
    
    #include<windows.h>
    
    #include<cstdio>
    
    using namespace std;
    
    JNIEXPORT void JNICALL Java_nativeDemo_NativeMain_helloC
      (JNIEnv *, jclass)
    {
        int x;
        x = MessageBox(GetForegroundWindow(),"【Java-JNI】","Hello World",1);
        printf("%d
    ",x);
    }

    这时调用MessageBox()函数可能会出错:不能将参数 2 从"const char [9]"转换为"LPCWSTR"这是Unicode的问题,项目菜单->最后的属性->配置属性->常规->项目默认值->unicode改为未设置。

    5.现在计算机基本都是64位的,要额外为64位计算机生成一个.dll文件

    如果没有X64点击下拉菜单,配置管理器配置一下。

    6.项目右键>生成,就有一个.dll文件了

    7.将hello.dll文件扔到D盘下,运行NativeMain类

    8.弹出框,成功弹出,并且打出日志。

     Native带来的缺陷

    我们已经成功调用一个非Java代码的接口,弥补Java的性能缺陷,会发现过程有点繁琐。使用后给我们带来什么影响?

    1. 牺牲Java的安全性,无法受到安全网的保护。
    2. 必须格外留意应用程序中的代码,并使用良好的实践来保障应用程序的总体完整性,否则可能导致性能变差,甚至程序崩溃。
    3. Java的可移植性变差。

    总结

    native关键字修饰的函数(方法),说明这个函数是原生函数,也就是这个函数是用C/C++语言实现的,并且被编译成了DLL,由java去调用。

    参考:《自己实现一个Native方法调用》

    ==========================================================================

    发现错误,请留言,lz及时修改,避免误导后来者,感谢!!!

  • 相关阅读:
    无法在WEB服务器上启动调试
    Zedgraph悬停时显示内容闪烁的解决
    用ZedGraph控件作图圆
    34.node.js之Url & QueryString模块
    33.Node.js 文件系统fs
    32.Node.js中的常用工具类util
    31.Node.js 常用工具 util
    30.Node.js 全局对象
    28.Node.js 函数和匿名函数
    27.Node.js模块系统
  • 原文地址:https://www.cnblogs.com/dslx/p/10668733.html
Copyright © 2011-2022 走看看