Atitit.java jna 调用c c++ dll的原理与实践 总结v2 q27
1.Jna简单介绍
原来使用JNI,你必须手工用C写一个动态链接库,在C语言中映射Java的数据类型。
JNA中,它提供了一个动态的C语言编写的转发器,可以自动实现Java和C的数据类型映射,你不再需要编写C动态链接库。
2.Jna范例halo owrld
importcom.sun.jna.Library;
importcom.sun.jna.Native;
importcom.sun.jna.Platform;
/** Simple example of JNA interface mapping and usage. */
publicclassHelloWorld {
// This is the standard, stable way of mapping, which supports extensive
// customization and mapping of Java to native types.
publicinterfaceCLibraryextendsLibrary {
CLibrary INSTANCE = (CLibrary)
Native.loadLibrary((Platform.isWindows() ?"msvcrt":"c"),
CLibrary.class);
voidprintf(String format, Object... args);
}
publicstaticvoidmain(String[] args) {
CLibrary.INSTANCE.printf("Hello, World\n");
for(inti=0;i
CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]);
}
}
}
指定c类库dll路径msvcrt,没有采用全路径,会自动搜索系统路径下面的。
C:\Windows\winsxs\amd64_microsoft-windows-msvcrt_31bf3856ad364e35_6.1.7600.16385_none_2d4a27c7b8972454\msvcrt.dll
作者::绰号:老哇的爪子(全名::AttilaxAkbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 )汉字名:艾龙,EMAIL:1466519819@qq.com
转载请注明来源:http://www.cnblogs.com/attilax/
3.Jna概念
JNA把一个dll/.so文件看做是一个Java接口。
Dll是C函数的集合、容器,这正和接口的概念吻合。
3.1.(1)需要定义一个接口,继承自Library或StdCallLibrary
默认的是继承Library,如果动态链接库里的函数是以stdcall方式输出的,那么就继承StdCallLibrary,比如众所周知的kernel32库。比如上例中的接口定义:
1
2
3
publicinterfaceCLibraryextendsLibrary {
}
3.2.2)接口内部定义
接口内部需要一个公共静态常量:INSTANCE,通过这个常量,就可以获得这个接口的实例,从而使用接口的方法,也就是调用外部dll/so的函数。
该常量通过Native.loadLibrary()这个API函数获得,该函数有2个参数:
·第一个参数是动态链接库dll/so的名称,但不带.dll或.so这样的后缀,这符合JNI的规范,因为带了后缀名就不可以跨操作系统平台了。搜索动态链接库路径的顺序是:先从当前类的当前文件夹找,如果没有找到,再在工程当前文件夹下面找win32/win64文件夹,找到后搜索对应的dll 文件,如果找不到再到WINDOWS下面去搜索,再找不到就会抛异常了。比如上例中printf函数在Windows平台下所在的dll库名称是 msvcrt,而在其它平台如Linux下的so库名称是c。
·第二个参数是本接口的Class类型。JNA通过这个Class类型,根据指定的.dll/.so文件,动态创建接口的实例。该实例由JNA通过反射自动生成。
接口中只需要定义你要用到的函数或者公共变量,不需要的可以不定义,如上例只定义printf函数:
4.数据类型映射NA官方给出的默认类型映射表如下:
参见参考
5.JNA能完全替代JNI吗?
这可能是大家比较关心的问题,但是遗憾的是,JNA是不能完全替代JNI的,因为有些需求还是必须求助于JNI。
使用JNI技术,不仅可以实现Java访问C函数,也可以实现C语言调用Java代码。
而JNA只能实现Java访问C函数,作为一个Java框架,自然不能实现C语言调用Java代码。此时,你还是需要使用JNI技术。
JNI是JNA的基础,是Java和C互操作的技术基础。有时候,你必须回归到基础上来。
6.参考
Atitit.java jna 调用c++ dll的总结
使用JNA访问Java外部函数接口- OPEN开发经验库.htm
paip.java 调用c++ dll so总结- attilax的专栏-博客频道- CSDN.NET.htm
参考Java调用.dll文件-抹去浮华,沉淀深度- ITeye技术网站.htm (jnative)学习JNA,Jnative个人总结- 80后的梦想- ITeye技术网站.htm(impt)Java JNA 详解-梦想是奢侈品,向奢侈品进军-博客频道- CSDN.NET.htm本文原名《使用JNA方便地调用原生函数》发表于2009年3月的“程序员”杂志上。[-]介绍实现原理调用原生函数使用JNA调用原生函数调用原生函数的模式和原生代码的类型映射和操作系统数据类型的对应表支持常见的数据类型的映射模拟结构体使用JNA调用使用Struct的C函数说明模拟复杂结构体结构体内部可以包含结构体对象的数组结构体内部可以包含结构体对象的指针的数组代码通过回调函数实现原生代码调用Java代码回调函数说明模拟指针使用PointerByReference模拟指向指针的指针模拟指针类详解