首页 > 编程语言 >HelloWorld之Java调用C++(JNI)

HelloWorld之Java调用C++(JNI)

时间:2023-02-07 12:00:38浏览次数:55  
标签:lang java Utf8 HelloWorld C++ Java JNI include hello

JNI(Java Native Interface),通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。

JNI技术博客:https://blog.csdn.net/m0_37537867/article/details/124137225

1、java新建类HelloWorld,并声明native方法,引入hello的dll

public class HelloWorld {
    public native void hello();

    static{
        System.loadLibrary("hello");
    }

    public static void main(String[] args){

        new HelloWorld().hello();
    }
}

 

2、编译生成.class文件

javap HelloWorld.java

3、使用javah生成.h头文件,【生成的HelloWorld.h 不要做任何修改】

javah 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、使用C或C++实现hello()方法

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

 

5、将jni_md.h文件拷贝到include文件夹下

sudo cp /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/include/darwin/jni_md.h /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/include

6、将.c文件编译并生成动态链接库

其中:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/include

替换为本地的jdk路径中的include文件路径

gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/include HelloWorldImpl.c -o libhello.jnilib

gcc -dynamiclib -I 这里是include路径 HelloWorldImpl.c -o libhello.jnilib

生成的动态链接库,libhello.jnilib 对应 java代码中的 hello,这里映射大小写不敏感

也就是libhello.jnilib 可以映射到 HELLO、hello、Hello、HellO等

也就是libHELLO.jnilib 可以映射到 HELLO、hello、Hello、HellO等

7、查看当前目录文件信息

8、运行java的main方法

java HelloWorld

9、查看HelloWorld的字节码

javap -c -v HelloWorld.class > HelloWorld.txt

字节码如下所示:

Classfile /Users/pfzheng/Downloads/demo/HelloWorld.class
  Last modified 2023-2-7; size 442 bytes
  MD5 checksum 21235e46a38830416fd799866dd7b048
  Compiled from "HelloWorld.java"
public class HelloWorld
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #7.#18         // java/lang/Object."<init>":()V
   #2 = Class              #19            // HelloWorld
   #3 = Methodref          #2.#18         // HelloWorld."<init>":()V
   #4 = Methodref          #2.#20         // HelloWorld.hello:()V
   #5 = String             #12            // hello
   #6 = Methodref          #21.#22        // java/lang/System.loadLibrary:(Ljava/lang/String;)V
   #7 = Class              #23            // java/lang/Object
   #8 = Utf8               <init>
   #9 = Utf8               ()V
  #10 = Utf8               Code
  #11 = Utf8               LineNumberTable
  #12 = Utf8               hello
  #13 = Utf8               main
  #14 = Utf8               ([Ljava/lang/String;)V
  #15 = Utf8               <clinit>
  #16 = Utf8               SourceFile
  #17 = Utf8               HelloWorld.java
  #18 = NameAndType        #8:#9          // "<init>":()V
  #19 = Utf8               HelloWorld
  #20 = NameAndType        #12:#9         // hello:()V
  #21 = Class              #24            // java/lang/System
  #22 = NameAndType        #25:#26        // loadLibrary:(Ljava/lang/String;)V
  #23 = Utf8               java/lang/Object
  #24 = Utf8               java/lang/System
  #25 = Utf8               loadLibrary
  #26 = Utf8               (Ljava/lang/String;)V
{
  public HelloWorld();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 6: 0

  public native void hello();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_NATIVE

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: new           #2                  // class HelloWorld
         3: dup
         4: invokespecial #3                  // Method "<init>":()V
         7: invokevirtual #4                  // Method hello:()V
        10: return
      LineNumberTable:
        line 15: 0
        line 16: 10

  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: ldc           #5                  // String hello
         2: invokestatic  #6                  // Method java/lang/System.loadLibrary:(Ljava/lang/String;)V
         5: return
      LineNumberTable:
        line 10: 0
        line 11: 5
}

 

SourceFile: "HelloWorld.java"

在上述字节码中可以看到hello()方法,被标识为ACC_NATIVE

10、安装IDEA插件jclasslib 查看字节码

插件主页:https://plugins.jetbrains.com/plugin/9248-jclasslib-bytecode-viewer

安装成功后,在View -> Show Bytecode with jclasslib

标签:lang,java,Utf8,HelloWorld,C++,Java,JNI,include,hello
From: https://www.cnblogs.com/zpfbuaa/p/17097910.html

相关文章

  • Java基础-反射
    Class类对象的获取根据类名:类名.class根据对象:对象.getClass()根据全限定类名:Class.forName(全限定类名)例子interfaceI1{}interfaceI2{}classCell{......
  • JavaScript 使用 !! 运算符的利弊
    !!运算符是在JavaScript中将一个值转换为布尔值的常用方法。使用这个运算符的优点是:简单易用:它只需要一行代码就可以完成转换,而不需要使用其他的方法。可读性:它很......
  • java中注解的使用
    1、注解是一种能被添加到java源代码中的元数据,方法、类、参数和包都可以用注解来修饰。注解可以看作是一种特殊的标记,可以用在方法、类、参数和包上,程序在编译或者运行时可......
  • javaScript - String对象的创建,全部属性,常用方法,全部方法
    1.String对象的创建//方式1字面量方式varstr="levi";//方式2创建对象方式varstr=newString("levi"); 2.String对象的属性:属性描述constructor对创建......
  • java List转换为字符串的几种方法
    List转String(用分隔符隔开)使用for循环+StringBuilder的方式就不记了,写一种相对简约一点的做法:publicStringlistToString(Listlist,charseparator){......
  • Java中进行单元测试junit.Assert断言、Mockito模拟对象、verify验证模拟结果、Java8中
    场景Java8新特性-Stream对集合进行操作的常用API:​​Java8新特性-Stream对集合进行操作的常用API_霸道流氓气质的博客-博客_javalist.stream​​在上面使用流操作时需要用到......
  • QML教程(七) JavaScript
    目录一、对属性值使用JavaScript表达式二、在QML中添加JavaScript函数三、使用JavaScript文件四、属性绑定中的JavaScript五、信号处理程序中的JavaScript......
  • javaFX的几个新特性,让swing彻底过时
    首先声明,Java的GUI曾经是最弱的一环,毋庸置疑,而且历史上因为跟M$的斗争,导致Java失去了Desktop发展的最佳时间点,即便后来SUN&Oracle推出了JavaFX,Desktop......
  • QML概念及框架--继承JavaScript
    QML推荐使用属性绑定和现有的QML元素来创建界面。为了允许执行更高级的行为,QML紧密集成了必要的JavaScript代码。QML中提供的JavaScript环境比在网页浏览器中的更严格。在Q......
  • Java 图形验证码
    简介Java图形验证码,支持Gif、中文、算术等类型,可用于JavaWeb、JavaSE等项目。效果展   集成项目maven方式引入:<dependency><groupId>com.git......