`
david_je
  • 浏览: 372003 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java Programming Tutorial-JNI(翻译)

    博客分类:
  • java
 
阅读更多

 1. 介绍

       在java编程中,有时候为了克服内存管理和性能限制,可能需要从java代码中去调用native的代码(像C/C++)。Java中的JNI就提供了这种调用机制。

JNI有点难,因为它涉及到两种编程语言的调用和运行。

JNI编程需要的基本知识有:

  1.       Java.
  2.       C/C++ 和GCC编译器(GCC and Make)
  3.       Gygwin or MinGW
  4.       Eclipse C/C++ Development Tool(CDT)

  2. 开始

       JNI和C

       第一步:编译一个使用C代码的Java类  HelloJNI.java

        

public class HelloJNI {
   static {
      System.loadLibrary("hello"); // hello.dll (Windows) or libhello.so (Unixes)
   }
   // A native method that receives nothing and returns void
   private native void sayHello();
 
   public static void main(String[] args) {
      new HelloJNI().sayHello();  // invoke the native method
   }
}

    当这个类加载时, 静态初始化加载器去调用了System.LoadLibrary()用来加载native库 "Hello",这个库中包括一个native的方法sayHello()。它在Windows系统中运行时,加载的库是“Hello.dll”,在Unix系统中运行时,加载的库是“libhello.so”。这个库必须加到Java的库路径中,或者在java运行时,使用java.library.path来告诉虚拟机它的路径。否则虚拟机将会抛出异常UnstisfiedLinkError。所以在Eclipse中执行时,在VM argument选项中加入参数 -Djava.library.path=path_to_lib.

 

     接着,我们使用native关键字声明了sayHello方法作为一个native的方法,他表示这个方法在其他语言中被实现了。所以在java代码中native方法是没有被实现,仅有一个声明。SayHello在native库加载的是时候被加载。

    

      第二步:创建C/C++的头文件  HelloJNI.h

      使用java提供的命令javah就可以自动创建一个C/C++的头文件。

      

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */
 
#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloJNI
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloJNI_sayHello
  (JNIEnv *, jobject);
 
#ifdef __cplusplus
}
#endif
#endif

 

 

     这个头文件声明了一个C的函数JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIENV *, jobject).函数名约定的方式是Java_{package_and_classname}_{function_name}(JNI arguments). 在包名中的'.'将被下划线代替。

      参数JNIEnv*代表JNI的环境,可以让你访问所有的JNI函数。

      参数jobject代表java中的this

      extern "C" 表示能被C++编译器识别,提醒C++编译器,这些函数时C的命名协议。C/C++拥有不同的命名协议和方式。C++ 支持函数重载,使用一个叫做name mangling scheme来区分重载的函数。

 

      第三步: C 的代码实现

      

#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"
 
JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
   printf("Hello World!\n");
   return;
}

    

     保存文件,命名为HelloJNI.c,这个程序仅仅只是打印Hello World,编译这个程序在windows系统上使用MinGW GCC命令:

    

gcc -Wl,--add-stdcall-alias -I"<JAVA_HOME>\include" -I"<JAVA_HOME>\include\win32" -shared -o hello.dll HelloJNI.c

 

    解释:

    

The compiler options used are:
-Wl: The -Wl to pass linker option --add-stdcall-alias to prevent UnsatisfiedLinkError (symbols with a stdcall suffix (@nn) will be exported as-is and also with the suffix stripped). (Some people suggested to use -Wl,--kill-at.)
-I: for specifying the header files directories. In this case "jni.h" (in "<JAVA_HOME>\include") and "jni_md.h" (in "<JAVA_HOME>\include\win32"), where <JAVA_HOME> denotes the JDK installed directory. Enclosed the directory in double quotes if it contains spaces.
-shared: to generate share library.
-o: for setting the output filename "hello.dll".

    

   也可以让编译和链接分两步来:

    

// Compile-only with -c flag. Output is HElloJNI.o
> gcc -c -I"<JAVA_HOME>\include" -I"<JAVA_HOME>\include\win32" HelloJNI.c
 
// Link into shared library "hello.dll"
> gcc -Wl,--add-stdcall-alias -shared -o hello.dll HelloJNI.o

    

     使用nm可以查找dll中的函数 nm hello.dll|grep say

 

     对于在Windows系统上的Gygwin GCC, 需要定义使用-D _int64="long long"来定义__int64为long long

     对于gcc-3,它提供了-mno-cygwin选项来编译DLL文件,而且不依赖Cygwin的库文件。

     

gcc-3 -D __int64="long long" -mno-cygwin -Wl,--add-stdcall-alias 
  -I"<JAVA_HOME>\include" -I"<JAVA_HOME>\include\win32" -shared -o hello.dll HelloJNI.c

 

     第四步: 运行

      

> java HelloJNI
or
> java -Djava.library.path=. HelloJNI

    

   

 

   原文来之于http://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

 

分享到:
评论

相关推荐

    java-tutorial-2008-03-14

    Java教程2008-03-14 这篇教程主要涵盖了2008年3月14日时Java编程语言的关键概念和技术。Java是一种广泛使用的面向对象的编程语言,以其跨平台的能力、高效性和安全性而闻名。在这个教程中,我们将深入探讨以下几个...

    Java2 Tutorial-5.0

    《Java2 Tutorial-5.0》是一份针对Java 2平台第五版(也称为Java 5.0)的详尽教程,旨在帮助开发者深入理解和掌握Java编程语言的关键概念和技术。这个教程涵盖了广泛的Java编程主题,从基础语法到高级特性,为初学者...

    PyQt5-Chinese-tutorial-master 中文翻译

    这个"PyQt5-Chinese-tutorial-master 中文翻译"项目是一个专门针对PyQt5的中文教程,对于初学者和有经验的开发者来说都是极其实用的资源。 教程首先可能会介绍PyQt5的基础知识,包括如何安装和配置PyQt5环境,讲解...

    Verbs programming tutorial-final.pdf

    SR-IOV and IOMMU/VT-d must be enabled in BIOS intel_iommu=on option must be specified in kernel command line - to check: cat /proc/cmdline - to setup: edit and configure bootloader files (GRUB/GRUB2)

    The-Java-Tutorial-Fourth-Edition.rar_The java tutorial

    《Java教程》第四版是Java开发者的重要学习资源,它详细介绍了Java编程语言的核心概念和技术。这本书的电子版以CHM(MicrosoftCompiled HTML Help)格式提供,便于在计算机上离线查阅。以下是对这个压缩包中包含的...

    NET-SNMP-TUTORIAL-MIB.txt

    是net-snmp官网上的TUTORIAL-MIB文件,由于官网不太容易登陆,因此贴在这里供大家下载!

    java-servlets-jsp-tutorial-en.rar_This Is It

    本教程的"java-servlets-jsp-tutorial-en.pdf"将详细讲解Servlets、JSP和Structs的使用方法,包括基础概念、配置、开发实践和示例代码,帮助读者掌握这些核心技术。通过学习,开发者将有能力构建复杂的企业级Web应用...

    spring-security-samples-tutorial-3.1.0.CI-SNAPSHOT.war

    spring的安全框架演示demo,这个是简单的,适合初学者

    VASP-tutorial-DielectricsRPA.zip资料vasp密度泛函DFT模拟计算态资料文档下载

    VASP-tutorial-DielectricsRPA.zip资料vasp密度泛函DFT模拟计算态资料文档下载VASP-tutorial-DielectricsRPA.zip资料vasp密度泛函DFT模拟计算态资料文档下载VASP-tutorial-DielectricsRPA.zip资料vasp密度泛函DFT...

    Tutorial-i386.exe

    本资源为Cheat Engine 训练教程,本教程将尝试讲解在游戏中作弊的一些基本知识,并帮助你熟悉 Cheat Engine 的使用方法。通过本应用,可以帮助新人快速入门CE的基本操作方法。如查找数据,修改数据等等

    jbehave-tutorial-maste

    这个“jbehave-tutorial-maste”压缩包很可能是JBehave的一个教程项目,旨在帮助用户了解并熟悉JBehave的基本用法和核心概念。 在JBehave中,故事是BDD的核心,它们描述了系统的功能需求,通常以简洁明了的文本形式...

    kurento-tutorial-java,.zip

    版权所有2018 Kurento。根据Apache2.0许可证授权。

    ecos-tutorial-i386PC

    #### 标题与描述解析:“ecos-tutorial-i386PC” 标题“ecos-tutorial-i386PC”指向的是针对eCos(嵌入式可配置操作系统)在i386PC平台上的入门教程。这一教程旨在为用户提供在特定硬件架构(即i386PC)上安装、...

    uanaoeng-javatutorial-master_php源码_腾讯翻译调用_

    在本项目"uanaoeng-javatutorial-master_php源码_腾讯翻译调用_"中,我们关注的主要焦点是PHP编程语言与腾讯翻译API的整合应用。这个项目旨在展示如何利用PHP来调用腾讯的翻译服务,从而实现跨语言的信息处理。我们...

    OpenCV-Python-Tutorial-master

    OpenCV-Python-Tutorial-master OpenCV-Python-Tutorial-master OpenCV-Python-Tutorial-master‘ opencv的演习源代码和图片

    sentinel-tutorial-master.zip

    sentinel-tutorial-master.zipsentinel-tutorial-master.zipsentinel-tutorial-master.zipsentinel-tutorial-master.zipsentinel-tutorial-master.zipsentinel-tutorial-master.zip

    IntelliJ-IDEA-Tutorial-newMaster

    IntelliJ IDEA,被誉为最优秀的集成开发环境(IDE),是JetBrains公司推出的一款强大的Java开发工具。它以其卓越的代码智能提示、高效的项目管理和丰富的插件支持,深受广大开发者喜爱。在本教程“IntelliJ IDEA ...

    ug936-vivado-tutorial-programming-debugging.pdf

    该教程“UG936-vivado-tutorial-programming-debugging.pdf”聚焦于Vivado中的编程与调试流程,版本号为2022.2,发布日期为2022年11月16日。Xilinx致力于创建一个包容性的工作环境,因此在产品和相关材料中移除可能...

Global site tag (gtag.js) - Google Analytics