首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java JNI 與 C++ 交互完整實戰教程

     編輯:Java 綜合教學

完整流程概覽

  1. 編寫 Java 類聲明 native 方法
  2. javac 編譯生成 .class
  3. javah 生成 C/C++ 頭文件
  4. 創建 C++ DLL 動態鏈接庫項目
  5. 配置包含目錄(JDK headers)
  6. 實現 native 方法
  7. 編譯生成 .dll/.so
  8. 將動態庫放入類路徑,運行 Java 程序

1. Java 程序

public class TestHello {
    static {
        System.loadLibrary("TestHello"); // 加載 TestHello.dll (Windows) 或 libTestHello.so (Linux)
    }
    
    public static native int add(int a, int b);
    
    public static void main(String[] args) {
        int c = add(2, 5);
        System.out.println("result:::::" + c);
    }
}

2. 編譯 Java

javac TestHello.java

3. 生成頭文件

javah TestHello

生成 TestHello.h,包含 JNI 規範的函數聲明:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#ifndef _Included_TestHello
#define _Included_TestHello
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_TestHello_add(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif

4. 創建 C++ DLL 項目

Visual Studio 2010:File → New → Project → Win32 Project → DLL → TestHello

5. 配置包含目錄

項目屬性 → Configuration Properties → C/C++ → General → Additional Include Directories 添加:

  • %JAVA_HOME%\include
  • %JAVA_HOME%\include\win32 (Windows)
  • 項目目錄(含 TestHello.h)

VS 包含目錄配置

6. 實現 Native 方法

TestHello.cpp

// TestHello.cpp : Defines the exported functions for the DLL application.
#include "stdafx.h"
#include "TestHello.h"
#include "dllApi.h"

JNIEXPORT jint JNICALL Java_TestHello_add(JNIEnv *env, jclass obj, jint a, jint b) {
    int var = 0;
    dllApi* test = new dllApi();
    var = test->DLL_API_ADD(a, b);
    delete test;
    return var;
}

dllApi.h

#pragma once
class dllApi {
public:
    dllApi(void);
    ~dllApi(void);
    int DLL_API_ADD(int, int);
    int DLL_API_SUB(int, int);
    int DLL_API_MUL(int, int);
    int DLL_API_DIV(int, int);
};

dllApi.cpp

#include "StdAfx.h"
#include "dllApi.h"

dllApi::dllApi(void) {}
dllApi::~dllApi(void) {}

int dllApi::DLL_API_ADD(int a, int b) { return (a + b); }
int dllApi::DLL_API_SUB(int a, int b) { return (a - b); }
int dllApi::DLL_API_MUL(int a, int b) { return (a * b); }
int dllApi::DLL_API_DIV(int a, int b) { return (a / b); }

7. 編譯生成 DLL

VS 中 Build → Build Solution,生成 TestHello.dll(Debug/Release 目錄)。

8. 運行驗證

# 將 dll 複製到 class 文件同級目錄
copy TestHello.dll .\

# 運行
java TestHello
# 輸出:result:::::7

關鍵注意事項

  • 函數命名規範:Java_類名_方法名(包名用下劃線分隔)
  • 數據類型映射:jint↔int、jdouble↔double、jstring↔String、jobject↔Object
  • JNIEnv*:JNI 環境指針,提供所有 JNI 函數調用入口
  • jclass:類引用(static 方法傳類,實例方法傳 this)
  • 內存管理:C++ new/delete 需配對,避免洩漏
  • 異常處理:C++ 異常不能直接拋給 Java,需用 ThrowNew 轉換
  • 跨平台:Linux 下編譯 .so,System.loadLibrary 自動加前綴 lib 和後綴 .so

進階擴展

  • 傳遞/返回數組:GetIntArrayElements/ReleaseIntArrayElements
  • 操作 Java 對象字段/方法:GetFieldID/SetIntField、GetMethodID/CallVoidMethod
  • JNI 註冊:JNI_OnLoad 動態註冊,避免命名規範限制
  • JavaCPP / JNA 等高級封裝庫簡化開發
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved