- 浏览: 7334297 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1546)
- 企业中间件 (236)
- 企业应用面临的问题 (236)
- 小布Oracle学习笔记汇总 (36)
- Spring 开发应用 (54)
- IBatis开发应用 (16)
- Oracle基础学习 (23)
- struts2.0 (41)
- JVM&ClassLoader&GC (16)
- JQuery的开发应用 (17)
- WebService的开发应用 (21)
- Java&Socket (44)
- 开源组件的应用 (254)
- 常用Javascript的开发应用 (28)
- J2EE开发技术指南 (163)
- EJB3开发应用 (11)
- GIS&Mobile&MAP (36)
- SWT-GEF-RCP (52)
- 算法&数据结构 (6)
- Apache开源组件研究 (62)
- Hibernate 学习应用 (57)
- java并发编程 (59)
- MySQL&Mongodb&MS/SQL (15)
- Oracle数据库实验室 (55)
- 搜索引擎的开发应用 (34)
- 软件工程师笔试经典 (14)
- 其他杂项 (10)
- AndroidPn& MQTT&C2DM&推技术 (29)
- ActiveMQ学习和研究 (38)
- Google技术应用开发和API分析 (11)
- flex的学习总结 (59)
- 项目中一点总结 (20)
- java疑惑 java面向对象编程 (28)
- Android 开发学习 (133)
- linux和UNIX的总结 (37)
- Titanium学习总结 (20)
- JQueryMobile学习总结 (34)
- Phonegap学习总结 (32)
- HTML5学习总结 (41)
- JeeCMS研究和理解分析 (9)
最新评论
-
lgh1992314:
[u][i][b][flash=200,200][url][i ...
看看mybatis 源代码 -
尼古拉斯.fwp:
图片根本就不出来好吧。。。。。。
Android文件图片上传的详细讲解(一)HTTP multipart/form-data 上传报文格式实现手机端上传 -
ln94223:
第一个应该用排它网关吧 怎么是并行网关, 并行网关是所有exe ...
工作流Activiti的学习总结(八)Activiti自动执行的应用 -
ZY199266:
获取不到任何消息信息,请问这是什么原因呢?
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息 -
xiaoyao霄:
DestinationSourceMonitor 报错 应该导 ...
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息
使用JNA简单调用DLL里的函数
1、在VC下创建一个动态链接库项目testJNA
2、在头文件里声明函数
extern "C" _declspec(dllexport) int add(int first, int second);
红色字体部分是必须的,包括定义结构体时也需要。应该是说此函数是发布的。
3、在源码里实现函数
int add(int first, int second) { printf("(c) test jna : %d + %d = %d", first, second, first + second); return first + second; }
4、生成dll文件
5、定义一个表示链接库的接口
接口TestJnaLib继承自com.sun.jna.Library,此接口有一个实例
TestJnaLib INSTANCE = (TestJnaLib)Native.loadLibrary("testJNA.dll", TestJnaLib.class);
此实例由jna通过反射自动生成。
6、定义对应dll里的方法
int add(int first, int second);
7、调用本地方法
TestJnaLib.INSTANCE.add(3, 5);
Jna回调Java方法:
1、在C语言部分定义带回调函数的函数
extern "C" _declspec(dllexport) void methodWithCallback(int (*fp)(int left, int right), int left, int right);
红色加粗部分是函数指针。
2、Java部分定义一个回调接口
必须继承自com.sun.jna.Callback接口
public interface FunCallBack extends Callback { int invoke(int left, int right); }
Invoke方法里的参数顺序与C函数的对应
3、定义回调接口的实现
public class CallbackFunImpl implements FunCallBack { @Override public int invoke(int left, int right) { System.out.printf("in java :%d + %d = %d\n", left, right, left + right); return left + right; } }
4、在表示链接库实现的接口里定义要回调的本地函数
void methodWithCallback(Callback callback, int left, int right);
本地函数的函数指针用Callback 接口替代。
5、调用带函数指针的本地函数
TestJnaLib.INSTANCE.methodWithCallback(new CallbackFunImpl(), 4, 6)
1、编写需要使用Jni的Java类文件
public class JniCall { static { System.loadLibrary("testJNA"); } public native static int add(int first, int second); public static void main(String[] args) { int first = 3; int second = 4; System.out.printf("print in java : %d + %d = %d", first, second, add(first, second)); } }
本地方法必须声明为native。
2、编译出class文件,用javah从class文件生成C的头文件JniCall.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class JniCall */ #ifndef _Included_JniCall #define _Included_JniCall #ifdef __cplusplus extern "C" { #endif /* * Class: JniCall * Method: add * Signature: (II)I */ JNIEXPORT jint JNICALL Java_JniCall_add (JNIEnv *, jclass, jint, jint); typedef struct Student { char * name; int age; int height; }StudentObj; #ifdef __cplusplus } #endif #endif
3、在VC下建立一个动态链接库项目testJNA
倒数第二个。
4、把生成的JniCall.h和$JAVA_HOME/include/jni.h、$JAVA_HOME/include/win32jni_md.h拷贝到vc项目testJNA的目录下
5、编写C的本地实现
#include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } JNIEXPORT jint JNICALL Java_JniCall_add(JNIEnv *, jclass, jint first, jint second) { printf("print in c : %d + %d = %d \n", first, second, first + second); return first + second; }
6、构建testJNA项目,生成testJNA.dll文件
7、把testJNA.dll拷贝到$JAVA_HOME/jre/bin目录下
8、运行Java类,调用本地方法
D:\Java\jdk1.6.0_02\bin>java JniCall
print in c : 3 + 4 = 7
print in java : 3 + 4 = 7
D:\Java\jdk1.6.0_02\bin>
JNA相关知识:
使用JNA调用原生函数的模式:
JNA不实用native关键字。
JNI使用native关键字,使用一个个java方法来代表外部的原生函数。
JNA使用一个java接口来代表一个动态链接库发布的所有函数。
对于不需要的原生函数,可以不在java接口中声明java方法原型。
使用JNI,需要使用System.loadLibrary方法,把专门为JNI编写的动态链接库载入进来,这个动态链接库实际上是真正需要的动态链接库的代理。
使用JNA类库的Native类的loadLibrary方法,是直接把需要的动态链接库载入进来。使用JNA不需要编写作为代理的动态链接库,不需要编写一行原生代码。
跨平台、跨语言调用原则:
尽量使用基本、简单的数据类型;
尽量少跨平台、跨语言传递数据!
Java调用原生函数时,会把数据固定在内存中,这样原生函数才可以访问这些Java数据。这些数据,JVM的GC不能管理,会造成内存碎片。
C语言的结构体是一个严格的规范,定义了内存的次序。因此,JNA中模拟的结构体的变量顺序绝对不能错。
Java调用动态链接库中的C函数,实际上就是把一段内存作为函数的参数传递给C函数。动态链接库以为这个参数就是C语言传过来的参数。
Structure类的write()方法会把结构体的所有字段固定住,是原生函数可以访问。
JNI技术是双向的,既可以从Java代码中调用原生函数,也可以从原生函数中直接创建Java虚拟机,并调用Java代码。
原生函数可以通过函数指针实现函数回调,调用外部函数来执行任务。这就是策略模式。
Callback:
任务回调定义必须继承自com.sun.jna.Callback接口,子类必须定义单个公有方法或一个名为callback的公有方法。必须持有到回调对象的一个存活引用。一个回调应该不抛出异常。
com.sun.jna.Library:
代表本地链接库的定义。可用如下形式定义:
MyNativeLibrary INSTANCE = (MyNativeLibrary)Native.loadLibrary("mylib", MyNativeLibrary.class);
虽然结构体和结构体字段的名字可以是任意的,但他们应该尽可能接近本地定义。参数名也一样。
此接口支持在Java端多线程、并发调用本地方法。如果本地类库不是线程安全的,可用
Native.synchronizedLibrary(com.sun.jna.Library)
来阻止多线程同时访问本地代码。
链接库的搜索路径:
jna.library.path 用户定义的路径;
Jna.platform.library.path 平台定义的路径,
com.sun.jna.Structure:
代表本地结构体的对等Java类。
当作为参数或返回值使用时,这个类被传递给struct * (指针);当作为另一个结构体的字段时,它被传递给struct (值传递)。
标记接口Structure.ByReference和Structure.ByValue被用来提醒默认的行为。
Structure属性传递给本地字段必须是public的。可以由下面可选的修饰符:
volatile JNA不会修改字段,除非被要求,通过writeField(String);
final JNA会通过read()覆写字段,字段在java这边是不可变的。
Structure属性的顺序与类型必须与本地结构体的字段一一对应。
发表评论
-
【转】Django resources
2014-01-23 14:35 10810Django resources This page li ... -
使用国内镜像源来加速python pypi包的安装
2014-01-16 11:16 197818pipy国内镜像目前有: http://pypi.d ... -
[转 ]vagrant使用简介
2014-01-10 13:53 257371> 简介: vagrant提供了易于配置,重复性 ... -
[转]在Java中调用Python
2014-01-07 13:08 9217在执行之前都需要把jython对应的包加载进去,这个是必须的 ... -
[转]Eclipse配置PyDev插件
2014-01-02 14:25 2835安装python解释器 安装PyDev: 首 ... -
RestFuse的研究(五) Http请求的封装
2014-06-14 15:50 3632在RestFuse中封装了Http请 ... -
RestFuse的研究(四) Junit的Statement的分析
2013-12-06 11:46 1667在RestFuse提供了多种单 ... -
RestFuse的研究(三) Junit的Rule的使用和分析
2013-12-06 11:01 2235在junit中定义一些可以公用的规则(R ... -
RestFuse的研究(二) Junit的Runner的分类和模式
2013-12-06 10:40 1601在Junit4中的调用JunitCore可以采 ... -
RestFuse的研究(一) HttpJunitRunner的实现
2013-12-06 10:11 1743在RestFuse是一种针对Rest We ... -
[转]An open-source JUnit extension to test HTTP/REST APIs
2013-12-06 09:57 1099http://developer.eclipsesource ... -
TestNG简单的学习(十三)TestNG中Junit的实现
2013-12-04 09:00 3354TestNG和junit的整合 ... -
TestNG简单的学习(十二)TestNG运行
2013-12-03 09:08 51577文档来自官方地址: ... -
TestNG简单的学习(十一)TestNG学习总结
2013-12-03 09:08 14183最近一直在学习关于TestNG方面的知识,根 ... -
TestNG简单的学习(十)TestNG @Listeners 的使用
2013-12-03 09:07 8690TestNG官方网站: http://testng.or ... -
TestNG简单的学习(九)TestNG Method Interceptors 的使用
2013-12-03 09:07 2712TestNG官方网站: http://testng ... -
TestNG简单的学习(八)TestNG Annotation Transformers 的使用
2013-12-03 09:07 2807TestNG官方网站: http://testng.or ... -
TestNG简单的学习(七)TestNG编程方式运行
2013-12-02 09:22 2450TestNG官方网站: http://testng.or ... -
TestNG简单的学习(六)测试工厂注释的使用
2013-12-02 09:22 2782TestNG官方网站: http://testng.or ... -
TestNG简单的学习(五)参数化测试数据的定制
2013-12-02 09:22 2698TestNG官方网站: http://testng.or ...
相关推荐
下面将详细阐述JNA的相关知识点。 ### JNA简介 JNA提供了一种方便的机制,使得Java程序可以无缝地访问本地库中的函数和数据结构。它的主要优点是减少了JNI的复杂性,同时也避免了生成和管理C头文件、实现文件以及...
### Java JNA 使用参考手册知识点概述 #### 一、JNA简介 JNA(Java Native Access)是一个基于经典JNI技术的Java开源框架,它允许Java应用程序动态地访问本机库,例如Windows系统的.dll文件,而无需编写任何JNI或...
在JNA 3.2.1中,你可以找到以下关键知识点: 1. **JNA架构**:JNA的核心设计是基于一个动态链接库(DLL或SO文件),这个库包含了一个映射机制,将Java中的方法映射到本地库的函数。通过`com.sun.jna.Library`接口,...
**详细知识点:** 1. **JNA工作原理**:JNA通过映射Java方法到本地函数,使得Java可以直接调用本机函数。它使用接口指针(Interface Pointer)来代表本地函数,这些接口在运行时被加载并解析为本地函数地址。 2. *...
在使用JNA时,有以下几个关键知识点: 1. **接口映射**:JNA的核心机制是将Java接口映射到本地库函数。定义一个接口,然后使用`@Native`注解标记,表示这个接口代表了本地库的函数。接口中的方法签名应与本地函数的...
### JNA框架帮助文档知识点详解 #### 一、引言 在Java开发中,有时候我们需要调用特定平台下的本地库文件来实现某些功能,而传统的做法是通过Java Native Interface (JNI)来完成这一任务。然而,使用JNI进行本地库...
本文将深入探讨JNA在处理复杂结构体传递,包括结构体数组和结构体指针方面的知识。 JNA是一种Java库,允许Java代码直接调用本机API,而无需编写JNI代码。相比于JNI,JNA的使用更为简单和直观,但可能在性能上稍逊...
在《com.sun.jna.examples》中,我们主要会探讨以下几个关键知识点: 1. **JNA的基本原理**:JNA通过映射Java接口到本地函数,实现跨语言调用。它定义了一种结构,将Java方法签名转换为本地函数调用的规范,从而...
以下是一些关于JNA的基础知识和使用步骤: 1. **JNA原理**:JNA的核心是映射机制,它将Java方法映射到本地函数,并将数据类型转换为本地平台兼容的格式。JNA使用一个配置文件(通常名为`native.lib`),该文件定义...
在给定的资源中,包含的是JNA 3.5.1版本的jar包以及相关的使用文档。 **JNA 3.5.1 jar包** 包含了JNA的核心库,它是Java程序调用原生函数的基础。这个jar文件提供了接口和类,使得开发者能够定义原生函数接口,并...
以下是关于JNA的一些关键知识点: 1. **JNA原理**:JNA通过动态加载库和映射函数,将C/C++的函数调用转化为Java方法调用。它通过一个映射表(Interface Mapping Table)将Java接口方法与原生库函数对应起来,实现了...
JNA 的主要功能和知识点包括: 1. **接口映射**:JNA 提供了一种定义 native 接口的方式,通过 Java 类和方法来映射本地库中的函数。例如,你可以定义一个接口,然后 JNA 会自动处理调用本地函数的细节。 2. **...
- 引入依赖:在Android项目中,需要将JNA和平台相关的jar包添加到项目的依赖中。 - 定义接口:创建一个Java接口,声明要调用的本地库函数。接口方法的参数和返回类型应与C函数匹配。 - 注册库:使用`Library`注解...
描述中的信息比较简单,没有提供具体的细节,但我们可以根据"JNA"这个标签来深入讨论JNA的相关知识点。 1. **JNA的基本原理**:JNA通过维护一个映射表,将Java方法映射到本地函数调用。它使用一个动态生成的C语言...
以下是一些使用JNA在Android上开发的关键知识点: 1. **类型映射**:JNA通过自动类型映射简化了Java与本地函数的交互。例如,Java的`int`可以自动映射为C的`int`,`String`可以映射为`char *`等。 2. **...
#### 知识点一:JNA简介与原理 JNA(Java Native Access)是一种允许Java程序直接调用本机DLL或共享库中的函数的框架。它无需编写JNI(Java Native Interface)代码,使得开发人员能够轻松地在Java应用程序中集成...
标题 "JNA调用DLL函数" 涉及的核心知识点是Java Native Access (JNA) 和如何通过JNA调用Windows Dynamic Link Library (DLL) 文件中的函数。在Java编程环境中,JNA提供了一种无需编写JNI(Java Native Interface)...
在使用JNA时,有以下几个关键知识点: 1. **类型映射**:JNA自动将Java类型映射到相应的本地类型,例如,Java的`int`对应C的`int`,Java的`String`对应C的`char*`。对于复杂类型,如结构体或联合体,JNA允许用户...
**JNA基础知识** JNA提供了一种简单的方法,让Java代码能够访问和调用本地库中的函数,而无需编写JNI代码。它使用一个映射接口来定义本地函数,并且可以处理各种数据类型,包括基本类型、结构体、枚举等。JNA的核心...
JNI 允许 Java 程序和用其他编程语言编写的代码之间进行交互,不过使用 JNI 的难度较高,需要开发者同时具备 Java 和原生语言(如 C/C++)的知识,且需编写额外的动态链接库。因此,它常常让开发者望而却步。 JNA...