`
rensanning
  • 浏览: 3512109 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
Efef1dba-f7dd-3931-8a61-8e1c76c3e39f
使用Titanium Mo...
浏览量:37448
Bbab2146-6e1d-3c50-acd6-c8bae29e307d
Cordova 3.x入门...
浏览量:604173
C08766e7-8a33-3f9b-9155-654af05c3484
常用Java开源Libra...
浏览量:677836
77063fb3-0ee7-3bfa-9c72-2a0234ebf83e
搭建 CentOS 6 服...
浏览量:87155
E40e5e76-1f3b-398e-b6a6-dc9cfbb38156
Spring Boot 入...
浏览量:399713
Abe39461-b089-344f-99fa-cdfbddea0e18
基于Spring Secu...
浏览量:69034
66a41a70-fdf0-3dc9-aa31-19b7e8b24672
MQTT入门
浏览量:90403
社区版块
存档分类
最新评论

Java调用Native API之JNA

    博客分类:
  • Java
 
阅读更多
Java调用C/C++的Native API一般采用JNI(Java Native Interface),但是需要编写特殊的代码,方法、数据的映射也很复杂。JNA(Java Native Access)能够是Java代码很简单的调用到Native API(.dll、.so)。类似于.NET的P/Invoke(Platform Invoke)、Python的ctypes。最初是1999年SUN公司为开发NetBeans IDE而开发的,2006年开源。

https://github.com/twall/jna

目前版本: 4.1.0

先看一个简单的例子:调用Windows API的printf输出“Hello, World”。

JNA代码:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

public class HelloWorld1 {
    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary) Native.loadLibrary(
            Platform.isWindows() ? "msvcrt" : "c", CLibrary.class);

        void printf(String format, Object... args);
    }

    public static void main(String[] args) {
        CLibrary.INSTANCE.printf("Hello, World\n");
    }
}

第6行定义CLibrary映射到Native(继承JNA的Library)
第7,8行加载目标Native Lib(Windows:msvcrt.dll,也可以是自己的so或dll)
第10行映射Native方法
第14行作为Java的普通方法调用printf

这是一种静态的映射方法,以下也可以动态映射:
import com.sun.jna.Function;
import com.sun.jna.Platform;

public class HelloWorld2 {
    public static void main(String[] args) {
        String libraryName  = Platform.isWindows() ? "msvcrt" : "c";
        String functionName = "printf";

        // Function
        Function function = Function.getFunction(
            libraryName,
            functionName,
            Function.C_CONVENTION);

        // Invoke
        function.invoke(new Object[]{"Hello, world\n"});
    }
}


JNI来实现调用C写的方法:
1)编写HelloWorld.java
/* HelloWorld.java */
public class HelloWorld {
  public native void hello(); /* (1) */
  static {
    System.loadLibrary("helloworld"); /* (2) */
  }
  public static void main (String args[]) {
    HelloWorld h = new HelloWorld();
    h.hello(); /* (3) */
  }
}

2)编译java文件
引用
/usr/java/jdk1.7.0_45/bin/javac HelloWorld.java

3)生成JNI的HelloWorld.h
引用
/usr/java/jdk1.7.0_45/bin/javah -jni HelloWorld

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    hello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_hello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

4)编写HelloWorld.c
#include "HelloWorld.h"

JNIEXPORT void JNICALL Java_HelloWorld_hello
  (JNIEnv *env, jobject me)
{
  printf("Hello World\n");
}

5)编译HelloWorld.c
引用
gcc -fPIC -shared HelloWorld.c -I/usr/java/jdk1.7.0_45/include/ -I/usr/java/jdk1.7.0_45/include/linux/ -o libhelloworld.so

6)执行HelloWorld
引用
java -Djava.library.path=. HelloWorld


JNA来实现调用C写的方法:

1)编写hello.c
#include <stdio.h>

void hello ()
{
  printf("Hello World!\n");
}


2)编译hello.c
引用
gcc -fPIC -shared -o libhello.so hello.c


3)编写HelloJNA.java
import com.sun.jna.Library;
import com.sun.jna.Native;

interface HelloLib extends Library {
  HelloLib INSTANCE = (HelloLib) Native.loadLibrary("hello", HelloLib.class);

  void hello();
}

public class HelloJNA {
  public static void main(String[] args){
    HelloLib hello = HelloLib.INSTANCE;
    hello.hello();
  }
}


4)编译执行
引用
javac -cp jna-4.1.0.jar HelloJNA.java
java -cp .:jna-4.1.0.jar HelloJNA


参考:
http://en.wikipedia.org/wiki/Java_Native_Access
http://en.wikipedia.org/wiki/Java_Native_Interface
http://en.wikipedia.org/wiki/SWIG
http://www.swig.org/
http://en.wikipedia.org/wiki/Platform_Invocation_Services
http://www.atmarkit.co.jp/fjava/special/jna/jna_1.html
分享到:
评论

相关推荐

    jna-5.4.0.jar中文文档.zip

    jna-***.jar中文文档.zip,java,jna-***.jar,net.java.dev.jna,jna,***,com.sun.jna,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 ...

    Java调用dll的JNA参考手册

    This document is the API specification for the JNA library for simplified native library access for Java.

    jnaCan:Java 的 CAN 总线,使用 JNA 访问 Linux SocketCan API

    通过使用Java Native Access,无需编写本机代码即可访问SocketCan API。 这个项目是纯 Java 的(从技术上讲,JNA jar 包含一些小型现成的本机二进制库)。 该库目前仅支持原始罐头模式。 读取和写入调用将被阻塞。...

    jna包及示例和VS2010入门

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

    JNA 3.3.0 API

    JNA允许使用JAVA方法调用方式来直接调用本地函数.它提供了一个动态的C语言编写的转发器,自动实现JAVA类型和C类型的映射. JNA使用一个小型本地库存根来动态调用本地代码.开发者需要定义一个JAVA接口来描述本地库存的...

    vix4j:使用 JNA 的 VMware VIX API 的高级功能且易于使用的 Java 包装器

    此包装器使用来自 Vix SDK 的原生 Vix 库,使用 Java Native Access (JNA) - 可从。 包装器旨在易于使用并抽象到 VMware 虚拟化解决方案上的更高级别的虚拟机操作操作。 产品支持 去做 操作系统支持 尽管包装器目前...

    jna5.5.0--5.3.0.rar

    JNA(Java Native Access)框架是一个开源的Java框架,是SUN公司主导开发的。 JNA的安装很简单,把从官网下载的jna.jar包导入工作路径就可以了。 下面测试系统API的几个方法,如GetLocalTime(),GetSystemTime(),...

    mraa4j:英特尔 mraa 的 Java 库

    mraa4j 是使用 Java Native 接口的英特尔 librmraa C/C++ 库之上的一个薄层。 请按照 Intel 的了解 API 的介绍。 Java API 主要遵循 Intel 文档并进行了一些修改,使其更像 Java。 有了这个库,就可以从 Java 虚拟机...

    libhyphenjna:使用JNA的hunspell连字符C库的Java库

    native-lib中的二进制文件是使用native-build.pl脚本在各种平台上构建的,本机lib的源代码在native-src中,并且由未修改的hunspell源tar球和任何所需的差异组成。 我包含了一个名为native-build.pl的脚本,该脚本...

    hid4java-j15:hid4java(Java 1.5)for 0.3.1

    技术领域用于多个平台的本机USB HID库消除了对Java Native Interface(JNI)的需求,并大大简化了项目Java 6+-删除对寿命已尽的JVM的依赖Maven依赖我还没有将其放入Maven Central(在我的清单中),因此,作为临时...

Global site tag (gtag.js) - Google Analytics