zoukankan      html  css  js  c++  java
  • JNI编程实现(Windows)

    上一篇介绍了Linux平台的JNI编程方法,Windows平台的JNI本地调用基本类似,区别就是制作的动态库不同,Linux平台是*.soWindows平台是*.dll。其中,Windows平台的函数库也分为静态库和动态库,下面介绍一下相关概念:

    静态库
    在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中,这种库称为静态库。其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令都全部被直接包含在最终生成的EXE文件中了。在vs中新建生成静态库的工程,编译生成成功后,只产生一个*.lib文件

    动态库
    动态链接库是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个DLL中,该DLL包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。在vs中新建生成动态库的工程,编译成功后,产生一个.lib文件和一个.dll文件

    那么静态库中的lib和动态库中的lib究竟有什么区别呢?

    静态库中的lib:该lib包含函数代码本身(即包括函数的索引,也包括实现),在编译时直接将代码加入程序当中

    动态库中的lib:该lib包含了函数所在的dll文件和文件中函数位置的信息(索引),函数实现代码由运行时加载在进程空间中的dll提供

    本文制作动态库,即生成*.lib*.dll文件,使用Visual Studio 2017工具,步骤和linux平台的类似,下面详细介绍

    制作动态库

    1.编写native声明方法的java类

    编写Java类,声明一个native的本地方法

    public class Hello {
    	public native static String sayHello(String name);
    
    	static {
    		System.load("E:\Eclipse\Hello\libhello.dll");
    	}
    
    	public static void main(String[] args) {
    		Hello hello = new Hello();
    		String ret = hello.sayHello("kelvin");
    		System.out.println(ret);
    	}
    }
    

    2.编译java类

    使用javac进行编译

    #javac Hello.java
    

    3.生成本地文件*.h

    使用javah生成Hello.h头文件,依赖上一步的Hello.class

    # javah -jni Hello
    

    4.使用Visual Studio 2017创建构建动态库

    接下来,使用Visual Studio 2017制作动态库libhello.liblibhello.dll

    a、新建工程

    首先,新建工程,文件 -> 新建 -> 项目 -> Visual C++ -> Windows 桌面 -> 动态链接库(DLL)

    图1

    b、添加头文件

    把生成的本地头文件Hello.h导入到工程中;另外,还需要把jni.hjni_md.h这两个头文件也导入到工程中

    c、编写本地方法的实现

    新增Hello.cpp文件,编码实现本地方法

    #include "stdafx.h"
    #include <iostream>
    #include "Hello.h"
    
    using namespace std;
    
    JNIEXPORT jstring JNICALL Java_Hello_sayHello(JNIEnv *env, jclass jc, jstring name)
    {
    	const char *buf = { 0 };
    	buf = env->GetStringUTFChars(name, NULL);
    
    	cout << buf << endl;
    
    	return env->NewStringUTF("hello");
    }
    
    d、生成动态库

    编译工程,生成动态链接库。如果是64位系统,还需要设置Debugx64,否则会报错

    生成 -> 重新生成解决方案

    设置为64位系统的动态库

    图2

    5、调用动态库

    把工程的根目录下Debug中的libhello.dll拷贝到Hello.class目录,如果是x64则是在目录x64目录下;然后,调用Hello测试jni的本地调用

    # java -classpath E:EclipseHello Hello
    kelvin
    hello
    

    看到输出,表明了libhello.dll被正常加载调用了


    这就是Windows的本地调用,虽然Java程序中提倡单一语言风格,但是本地调用提供了一种解决方案,在Java语言无法实现时,选择使用jni也是一种合适的方式。

    参考资料

    java native方法与JNI实现
    lib 和 dll 的区别、生成以及使用详解

  • 相关阅读:
    eclipse中文乱码问题解决方案
    修改Tomcat的JDK目录
    Tomcat 5.5 修改服务器的侦听端口
    HTML DOM教程 27HTML DOM Button 对象
    HTML DOM教程 24HTML DOM Frameset 对象
    Navicat for MySQL v8.0.27 的注册码
    HTML DOM教程 25HTML DOM IFrame 对象
    Tomcat 5.5 的下载和安装
    android manifest相关属性
    ubuntu10.04 下 eclipse 小结
  • 原文地址:https://www.cnblogs.com/fishbay/p/10030042.html
Copyright © 2011-2022 走看看