Java calls the helloword test of C++ dynamic link library through JNI technology

JNI calling principle

I won’t go into details about the principle. In fact, it is to write a library for Java to adjust. You can search it on BaiduJava JNI. The following is the HelloWorld code test

Write a local test class

package com.my.study.cpp_jni;

/**
 * 测试Java调用C++库
 * <p>使用命令javac -h . NativeTest.java自动生成C头文件</p>
 * <p>到jdk中的include\win32下单jni.h和jni_md.h头文件拷过来</p>
 * <p>实现cpp文件</p>
 * <p>编译</p>
 * <p>导入</p>
 * <p>配置cpp库文件</p>
 * <p>System.load("D:/xxx/java/com/my/study/cpp_jni/MyLibrary.so");</p>
 *
 */
public class NativeTest {
    
    
    static {
    
    
        /*
        // 设置java.library.path路径
        System.setProperty("java.library.path", "/path/to/library");

        // 通过System.loadLibrary()加载库文件
        System.loadLibrary("mylibrary");
        */
        System.load("D:/xxx/java/com/my/study/cpp_jni/MyLibrary.dll");
    }

    private native void print();

    public static void main(String[] args) {
    
    
        new NativeTest().print();
    }
}

java file format description

Use the JavaC command to generate the C language header file .h file

Use the command javac -h . NativeTest.java to automatically generate the C header file

javac -h . NativeTest.java

Generate file com_my_study_cpp_jni_NativeTest.h:

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

#ifndef _Included_com_my_study_cpp_jni_NativeTest
#define _Included_com_my_study_cpp_jni_NativeTest
#ifdef __cplusplus
extern "C" {
    
    
#endif
/*
 * Class:     com_my_study_cpp_jni_NativeTest
 * Method:    print
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_my_study_cpp_jni_NativeTest_print
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

com_my_study_cpp_jni_NativeTest.h file format description

Copy the jni.h and win32/jni_md.h header files in the JDK include directory to the same path

Modify #include <jni.h> in the com_my_study_cpp_jni_NativeTest.h file to #include "jni.h" to avoid searching for C/C++ libraries
Insert image description here

NativeTest.cpp implements C header file functions

#include<iostream>
#include "com_my_study_cpp_jni_NativeTest.h"


using namespace std;
JNIEXPORT void JNICALL Java_com_my_study_cpp_jni_NativeTest_print(JNIEnv *, jobject) {
    
    
  	cout << "Hello Word JNI" << endl;
  }

Compile C++ library files

Compile C source code and create native libraries

//Compile C language library
// gcc -ID:\xxx\Java\Java8\jdk\include\ -ID:\xxx\Java\Java8\jdk\include \win32\ NativeTest.c -shared -o MyLibrary.so
// Compile C++ library
// g++ -ID:\xxx\Java\Java8\jdk \include\ -ID:\xxx\Java\Java8\jdk\include\win32\ NativeTest.cpp -shared -o MyLibrary.so
// gcc -I means to represent the following directory as Directory of the nth header file

Execute test and report error

Insert image description here

Solve the error problem and confirm whether the gcc and g++ versions are 32 or 64 bits

It is better to install vs directly for testing, because I spent several hours on the problem of not being able to find the library file. It is better to install vs directly. After installing vs, the dll library will be generated in a few minutes a> Here is the file structure just created based on the corresponding header file and cpp implementation file. The files are For the above file, just put the file in the corresponding location
Here I use VS2022 to generate a dynamic link library, install it and create a C++ project

Insert image description here

By the way, remove the pch.h precompiled header here, because it is not used, otherwise it will keep reporting errors.
Insert image description here

Use vs to generate a dynamic link library, and put the generated code in the root directory of drive D to facilitate testing. Modify the Java test code. Here you can see that the dynamic link library I generated using the g++ instruction is smaller than the dynamic link library generated using vs. , indicating that there is something missing in the dynamic link library generated using instructions. I am not familiar with C++, so I used vs to generate it here.
Insert image description here

/**
 * 测试Java调用C++库
 * <p>使用命令javac -h . NativeTest.java自动生成C头文件</p>
 * <p>到jdk中的include\win32下单jni.h和jni_md.h头文件拷过来</p>
 * <p>实现cpp文件</p>
 * <p>编译</p>
 * <p>导入</p>
 * <p>配置cpp库文件</p>
 * <p>System.load("D:/xxx/java/com/my/study/cpp_jni/_013_Cpp_VS_Dynamic_Link_Lib.dll");</p>
 * <p>System.loadLibrary("_013_Cpp_VS_Dynamic_Link_Lib");//不加dll</p>
 * Can't load IA 32-bit .dll on a AMD 64-bit platform:需要下载64位cpp编译器,不同cpu编译器不同
 */
public class NativeTest {
    
    
    static {
    
    
        System.load("D:/_013_Cpp_VS_Dynamic_Link_Lib.dll");
    }

    private native void print();

    public static void main(String[] args) {
    
    
        new NativeTest().print();
    }
}

idea running test:
Insert image description here
Here you can see the string Hello World JNI printed by running C++ compilation, it succeeded, spread the flowers

Summarize:

  1. Create a Java file and mark the function with native
  2. Generate .h header file
  3. Copy the jni.h, jni_md.h files and adjust the file reference position
  4. Implement header files
  5. Generate dynamic link library (VS is used here)
  6. Java call

Guess you like

Origin blog.csdn.net/qq_27577113/article/details/134359978