首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

C++ 與 Java 混合編程實戰:JNI 雙向調用完整指南

     編輯:關於VC++

背景與原理

現代項目常涉及多語言協作。C++ 與 Java 交互通過 JNI(Java Native Interface)實現:

  • Java 調用 C++:C++ 實現 JNI 生成的本地方法頭文件,編譯為共享庫,Java 通過 System.loadLibrary 加載調用
  • C++ 調用 Java:C++ 啟動 JVM,通過 JNI 查找類/方法並調用

環境配置

  • Java:JDK 1.6.0_03;C++:VC++ 6.0
  • 關鍵環境變量:JAVA_HOME、PATH 包含 %JAVA_HOME%\bin、%JAVA_HOME%\jre\bin\client(含 jvm.dll)
  • VC++ 包含目錄添加 %JAVA_HOME%\include、%JAVA_HOME%\include\win32;庫目錄添加 %JAVA_HOME%\lib

Java 調用 C++ 完整流程

1. Java 端聲明本地方法

public class WinFile {
    static { System.loadLibrary("WinFile"); } // 加載 libWinFile.dll
    public native String GetFilesFromDir(String path);
}

2. 生成 C/C++ 頭文件

javac WinFile.java
javah WinFile  // 生成 WinFile.h

3. C++ 實現與編碼轉換

JNIEXPORT jstring JNICALL Java_WinFile_GetFilesFromDir
  (JNIEnv *env, jobject obj, jstring jpath) {
    // UTF-8 -> GB2312
    const char* utf = env->GetStringUTFChars(jpath, 0);
    char* gb = Utf8ToGb2312(utf);
    env->ReleaseStringUTFChars(jpath, utf);
    // 業務邏輯...
    char* resultGb = DoWork(gb);
    // GB2312 -> UTF-8
    char* resultUtf = Gb2312ToUtf8(resultGb);
    jstring jresult = env->NewStringUTF(resultUtf);
    free(gb); free(resultGb); free(resultUtf);
    return jresult;
}

編譯:cl -GX -LD WinFile.cpp -FelibWinFile.dll

C++ 調用 Java 完整流程

1. Java 端定義靜態方法

public class WinFile {
    public static String Process(String input) { /* ... */ }
}

2. 獲取方法簽名

javap -s WinFile
// 輸出: Process(Ljava/lang/String;)Ljava/lang/String;

3. C++ 啟動 JVM 並調用

JavaVMOption options[1];
options[0].optionString = "-Djava.class.path=.";
JavaVMInitArgs vm_args = { JNI_VERSION_1_6, 1, options, JNI_FALSE };
JavaVM* jvm; JNIEnv* env;
JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

jclass cls = env->FindClass("WinFile");
jmethodID mid = env->GetStaticMethodID(cls, "Process", "(Ljava/lang/String;)Ljava/lang/String;");

jstring jinput = env->NewStringUTF(Gb2312ToUtf8("參數"));
jstring jresult = (jstring)env->CallStaticObjectMethod(cls, mid, jinput);
const char* utf = env->GetStringUTFChars(jresult, 0);
char* gb = Utf8ToGb2312(utf);
printf("Result: %s\n", gb);

env->ReleaseStringUTFChars(jresult, utf);
free(gb); jvm->DestroyJavaVM();

關鍵點:jvm.dll 必須通過系統路徑加載,不可複製至應用目錄(依賴 JRE 完整目錄結構)。

總結

混合編程核心難點在於編碼轉換(UTF-8 ↔ 本地編碼)與運行環境構建(JVM 初始化、庫路徑)。掌握雙向調用流程,可充分發揮 C++ 性能優勢與 Java 生態豐富性的互補價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved