`
longgangbai
  • 浏览: 7330376 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多

    JNA(Java Native Access )提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。

优点

  JNA可以让你像调用一般java方法一样直接调用本地方法。就和直接执行本地方法差不多,而且调用本地方法还不用额外的其他处理或者配置什么的,也不需要多余的引用或者编码,使用很方便。

JNA描述

  JNA类库使用一个很小的本地类库sub 动态的调用本地代码。程序员只需要使用一个特定的java接口描述一下将要调用的本地代码的方法的结构和一些基本属性。这样就省了为了适配多个平台而大量的配置和编译代码。因为调用的都是JNA提供的公用jar 包中的接口。

目标

  JNA是为了程序员调用本地代码更方便,跑的更快以及减少出错。

其他

  JNA中还包括了一些已经和某些特定平台的常用方法映射好的接口以及一些有用的可以简化本地代码访问的方法。

 

 

JNA编程基本语法解析
  1. 自定义一个接口,该接口继承(扩展)自com.sun.jna.Library接口,
 上面示例代码中的CLibrary接口。
 2 .在自定义的接口中声明将要调用的函数原型,这些函数原型必须要在即将
加载的动态库中有对应的实例。如上面示例代码中的printf函数声明。如果是在微软的Windows环境下,
该函数存放在msvcrt.dll动态库中;如果是在Linux环境下,该函数存放在libc.so动态库中。
 3. 在调用函数之前,先将接口实例化,并调用Native.loadLibrary对接口的实例初始化。
如上面示例代码中的Instance实例初始化。
 4. 在上面的操作都正常完成后,即可在有需要的地方调用对应的C/C++函数。

 

package com.etrip.jna.win;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
/**

 * 
 * @Title: TODO
 * @Description: 实现TODO
 * @Copyright:Copyright (c) 2011
 * @Company:
 * @Date:2012-12-14
 * @author longgangbai
 * @version 1.0
 */
public class HelloJNA
{
    //定义接口CLibrary,继承自com.sun.jna.Library
    public interface CLibrary extends Library
    {
    	//定义并初始化接口的静态变量
    	CLibrary Instance=(CLibrary)Native.loadLibrary((Platform.isWindows()?"msvcrt":"c"),CLibrary.class);
    	//printf函数声明
        void printf(String format, Object... args);
    }

    public static void main(String[] args) {
        CLibrary.Instance.printf("Hello, World/n");
        for (int i=0;i < args.length;i++) {
            CLibrary.Instance.printf("Argument %d: %s/n", i, args[i]);
        }

    }

}

 


 

 

Windows 下 JNI 备忘

 

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>

注意char *与string的映射问题,如果对编码又要求的话,最好采用以下这种方式将string传给本地方法。

比如要以gbk传字符串s给本地方法:call(char *)

byte[] bytes = (s+'\0').getBytes("gbk");
Dll.INSTANCE.call(bytes);

更多内容

_stdcall和_cdecl函数调用约定

_cdecl,是C语言缺省的调用约定,参数采用从左到右的压栈方式,函数本身不清理堆栈,调用者负责清理堆栈。对于这种库,只要直接继承Library

_stdcall,是Pascal程序的缺省调用方式,WIN32 Api都采用_stdcall调用方式。参数采用从右到左的压栈方式被调函数自身在返回前清空堆栈。这种需要继StdCallLibrary

分享到:
评论

相关推荐

    Java JNA使用参考手册.pdf

    ### Java JNA 使用参考手册知识点概述 #### 一、JNA简介 JNA(Java Native Access)是一个基于经典JNI技术的Java开源框架,它允许Java应用程序动态地访问本机库,例如Windows系统的.dll文件,而无需编写任何JNI或...

    jna-platform-4.0.0.jar、4.1.0.jar、4.2.0.jar、4.2.1.jar、4.2.2.jar及JNA使用方法、程序示例

    内部包含6个文件,其中五个是最新JNA jar包,包括jna-platform-4.1.0.jar、jna-platform-4.2.0.jar、jna-platform-4.2.1.jar、jna-platform-4.2.2.jar,一个是JNA介绍文档,包括在线帮助、入门示例、简单程序示例等...

    jna包及示例和VS2010入门

    JNA(Java Native Access )提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与...

    JNA示例的C++代码

    通过这个项目,开发者可以学习到如何使用JNA在Java应用程序中调用C++编写的DLL,理解结构体、函数指针和DLL的原理,以及如何在Visual Studio环境下构建和管理这样的项目。这是一次宝贵的跨语言编程实践,对于理解和...

    开源项目JNA-中文翻译版

    JNA入门 - **准备工作**:首先,需要下载并配置`jna.jar` 和 `example.jar` 文件。 - **环境搭建**:确保开发环境已经安装了Java Development Kit (JDK),并且设置了正确的环境变量。 ##### 2. 获取本地时间 - *...

    海康人脸设备上传文档以及说明文档/examples.jar/jna.jar

    综上所述,该压缩包为开发者或系统集成商提供了全面的资源,帮助他们理解和使用海康人脸设备,从设备的基本操作到高级的SDK开发,覆盖了从入门到进阶的全过程。无论是初次接触还是有经验的用户,都能从中获取所需的...

    JNI调用C++动态链接库入门

    ### JNI调用C++动态链接库入门:详细解析与实践指南 #### 一、引言 Java Native Interface(JNI)是Java平台提供的一种强大的机制,它允许Java代码调用本地的C或C++代码,从而利用这些语言在性能、系统访问等方面...

    tessdemo:使用JNA的Java中的Tesseract演示

    带有JNA(Tess4J)的Java中的Tesseract演示。 该演示将参加在MacOS,Ubuntu和Windows等多种操作系统上测试 。 Tesseract:一个开源的OCR引擎。 更多详细信息,请参见其。 图像过滤器:查看更多信息。 感谢这些...

    开源项目JavaNativeAccess借鉴.pdf

    在JNA入门示例中,通常会展示如何调用像Windows API中的`GetSystemTime()`这样的函数。这个函数返回系统当前的UTC时间。为了获取本地时间,可以使用`GetLocalTime()`函数,它同样位于`kernel32.dll`库中,但返回的是...

    java调用本地化(dll)实用文档

    JNA快速入门 - **步骤**: 1. **下载JAR包**:首先需要下载`jna.jar`,可以从官方或者其他可信网站获取。 2. **引入依赖**:将下载好的`jna.jar`添加到Java项目的类路径中。 3. **定义接口**:使用JNA提供的`...

    汇编语言(ASM)从入门到精通

    JBE/JNA(比较无符号数) 76 C或Z=1 低于或等于/不高于 JG/JNLE(比较带符号数) 7F (S异或O)或Z=0 &gt; 大于/不小于或等于 JGE/JNL(比较带符号数) 7D S异或O=0 &gt;= 大于或等于/不小于 JL/JNGE(比较带符号数) 7C S异或O...

    嵌入式开发学习笔记( java - c/c++ :从入门到入门 )

    3. JNA(Java Native Access):JNA是一个Java库,它提供了一种简易的方法,使得Java程序能够调用动态链接库(DLL或SO)中的函数,而无需编写JNI的本地方法接口。 4. DLL(Dynamic Link Library)和SO(Shared ...

    清华妹子的Java仓库(进阶学习路线)

    JNA:演示了JNA的基本用法,使用Java调用C++代码。 博客目录 Java基础 Java基础学习(1)——引用 Java基础学习(2)——注解 Java基础学习(3)——泛型 Java基础学习(4)——动态代理 《Java多线程核心技术》读书笔记 ...

    Test4j使用介绍

    本篇文章将深入探讨Test4j的基本使用方法,适合初学者入门。 **1. 安装与引入** 首先,要在项目中使用Test4j,你需要通过Maven或Gradle添加相应的依赖。在Maven的pom.xml文件中,添加以下依赖: ```xml ...

    JVisa:与VISA(虚拟仪器软件体系结构)仪器的接口

    入门 安装VISA实施 您必须安装VISA实施才能使用JVisa。 建议使用 。 据我所知,有四家公司编写了自己的VISA实现:Keysight,National Instruments,Rohde&Schwarz和Tektronix。 Nation Instruments的实现方式似乎...

    Android-基于speex的语音录制

    这些项目通常提供了详细的实现步骤和示例代码,可以帮助开发者快速入门。 以上就是关于“基于speex的语音录制”这一主题的主要知识点,通过理解并实践这些内容,开发者能够创建出高效、高质量的Android语音应用。

    java-rust-example-使用Java中的Rust-Rust开发

    OSX Linux Windows要求Java 7+ Rust(已经过1.0测试,每晚)该项目包含Rust代码和Java代码使用JNA的Rust接口的Java接口一个脚本将Rust代码构建到库中,并将其放在JNA可以找到它的类路径中Java和Rust入门最好的地方

    一、JAVA调用海康威视SDK实现摄像头预览

    对于海康威视的SDK,推荐使用JNA,因为它的使用更为简单且无需编译原生代码。 预览功能的实现主要包括以下几个步骤: 1. **初始化连接**:使用SDK提供的接口创建设备连接,通常需要输入设备的IP地址、端口号、...

    常用Jacob包

    Jacob(Java Object-Oriented Binding)...不过,随着技术的发展,一些新的库和框架如Apache POI、JACOB的替代品如JNA(Java Native Access)也逐渐出现,它们提供了更现代的解决方案,可能在某些场景下是更好的选择。

    嵌入式开发学习笔记

    文档中也提到了JNA(Java Native Access)作为JNI的一种替代技术,但在本笔记中作者选择了JNI,并对为什么没有使用JNA给出了自己的解释。 本笔记还提到了Makefile的使用,这是一种在Linux环境下自动化构建项目的...

Global site tag (gtag.js) - Google Analytics