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

Java 使用 JNA 呼叫 C/C++ DLL 完整教學

     編輯:Java 程式設計入門

什麼是 JNA?

JNA (Java Native Access) 建構於 JNI 之上,由 Sun 主導開發的開源框架。讓 Java 直接呼叫原生庫 (Windows .dll / Linux .so) 無需撰寫 C/C++ 胶水代碼,自動處理資料型別對應。雖效能略遜於 JNI,但開發效率大幅提升。

步驟 1:編寫原生 DLL (Visual Studio 範例)

main.h

#ifndef __MAIN_H__
#define __MAIN_H__

#include <windows.h>

#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport) __stdcall
#else
#define DLL_EXPORT __declspec(dllimport) __stdcall
#endif

#ifdef __cplusplus
extern "C" {
#endif

int DLL_EXPORT add(int a, int b);

#ifdef __cplusplus
}
#endif
#endif

main.cpp

#include "main.h"

int DLL_EXPORT add(int a, int b) {
    return a + b;
}

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
    return TRUE;
}

關鍵點:使用 __stdcall 呼叫慣例,配合 extern "C" 避免 C++ 名稱修飾。

步驟 2:Java 端介面定義

import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;

public class JnaDemo {

    // 繼承 StdCallLibrary 對應 __stdcall
    public interface CLibrary extends StdCallLibrary {
        CLibrary INSTANCE = (CLibrary) Native.loadLibrary("forjava", CLibrary.class);
        int add(int a, int b);
    }

    public static void main(String[] args) {
        System.out.println("2 + 3 = " + CLibrary.INSTANCE.add(2, 3));  // 輸出 5
    }
}

型別對應對照表

C/C++ 型別JNA 型別Java 型別
intintint
longlonglong
floatfloatfloat
doubledoubledouble
char*StringString
void*PointerPointer
struct*Structureextends Structure

進階主題

回呼函數

interface Callback extends StdCallLibrary {
    interface MyCallback extends StdCallCallback {
        void callback(int value);
    }
    void registerCallback(MyCallback cb);
}

結構體傳遞

class Point extends Structure {
    public int x, y;
    protected List<String> getFieldOrder() { return Arrays.asList("x", "y"); }
}

記憶體管理

  • JNA 自動管理 Native 記憶體,Pointer 需手動 free()
  • 大量呼叫時建議重用 Memory 物件減少 GC 壓力

常見問題排查

  • UnsatisfiedLinkError:DLL 路徑不在 java.library.path,或 32/64 位元不匹配
  • 呼叫慣例錯誤:Windows API 多為 StdCallLibrary,C 預設 Library (cdecl)
  • 中文亂碼:確認編碼一致,或用 WString / Native.toString(bytes, encoding)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved