現代項目常涉及多語言協作。C++ 與 Java 交互通過 JNI(Java Native Interface)實現:
System.loadLibrary 加載調用JAVA_HOME、PATH 包含 %JAVA_HOME%\bin、%JAVA_HOME%\jre\bin\client(含 jvm.dll)%JAVA_HOME%\include、%JAVA_HOME%\include\win32;庫目錄添加 %JAVA_HOME%\lib
public class WinFile {
static { System.loadLibrary("WinFile"); } // 加載 libWinFile.dll
public native String GetFilesFromDir(String path);
}
javac WinFile.java javah WinFile // 生成 WinFile.h
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
public class WinFile {
public static String Process(String input) { /* ... */ }
}
javap -s WinFile // 輸出: Process(Ljava/lang/String;)Ljava/lang/String;
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 生態豐富性的互補價值。