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

HelloWorld之Java调用C++(JNI)

时间:2023-03-26 11:03:00浏览次数:48  
标签:lang java Utf8 HelloWorld C++ Java JNI include hello

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

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、查看当前目录文件信息

HelloWorld之Java调用C++(JNI)_Java

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

HelloWorld之Java调用C++(JNI)_Java_02

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

HelloWorld之Java调用C++(JNI)_java_03

HelloWorld之Java调用C++(JNI)_java_04

作者: 伊甸一点

本文版权归作者伊甸一点有,欢迎转载和商用(须保留此段声明),且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.



标签:lang,java,Utf8,HelloWorld,C++,Java,JNI,include,hello
From: https://blog.51cto.com/u_9784906/6149934

相关文章

  • C++指针
    1指针的概念#include<iostream>usingnamespacestd;/*间接引用指针时,可获得该指针指向的变量内容本部分参考内容:C++程序设计教程钱能清华大学出版社*/void......
  • ubuntu20.04 安装TensorRT c++库
    官方那个文档上有很多中安装方法,这里采用压缩包安装,解压后直接将lib和include文件配置在环境变量里就ok了,对于c++来说是最方便的首先下载TensorRT:https://developer.nvidia.......
  • Javascript实现页面商品个数增减功能
    效果利用jQuery操作页面元素的方法,实现电商网站购物车页面商品数量的增加和减少操作,要求单项价格和总价随着数量的改变而改变当用户点击+按钮是,文本框中的商品数量增加1,......
  • Caused by: java.sql.SQLException: Parameter index out of range (2 > number of pa
    一、问题背景在xml配置中自定义了sql语句二、报错截图如下三、我的项目配置如下四、分析问题五、问题原因在xml中自定义sql语句时,里面不能有注释过得sql六、解决......
  • Java ThreadLocal
    ThreadLocal的功能在Java多线程并发环境中非常实用,其作用是提供线程本地变量,例如用户ID、会话ID等与当前线程密切关联的信息。那么它在实际业务场景中可以怎么使用呢?让我们......
  • java学习日记20230325-接口
    接口基本介绍 接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。    如果一个类implements,需要将该接口的......
  • JAVA入门基础
    JAVA入门打开CMDWin+R输入cmd.按下回车键Win+E打开我的电脑常见CMD命令盘符名称+冒号说明:盘符切换举例:E:回车,表示切换到E盘dir说明:查看当前路径下的内容......
  • 闭关java第四天
    Java方法详解什么是方法是语句的集合最好保持原子性:就是一个方法只完成一个功能,这样利于我们后期的拓展Java方法类似于其它语言的函数,是一段用来完成特定功能的代码片......
  • C/C++ 恨透了 double free or corruption
    *以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/IwSVImp5cOB3gZbaf0YiPw写过C/C++的都知道,内存允许程序员自主......
  • C++ sort 函数 以及 priority_queue 的使用
    1.sort函数的使用sort函数的定义:sort(first,end,compare);sort对[first,end)范围内的元素进行排序。默认为升序排序(此时不需要传入compare)。当需要降......