我必須圍繞現有的C源代碼編寫JNI包裝,以便可以從Java調用它們。但是大多數C源代碼都使用命令行參數(argc和argv)並廣泛使用它們。有沒有什麼方法可以將我在Java中捕獲的字符串args []傳遞給C函數,並對C源文件進行非常小的更改?圍繞C主函數編寫JNI封裝
我相信作爲JNI包裝的一部分,我必須在C編寫一個由Java代碼調用的函數。
我必須圍繞現有的C源代碼編寫JNI包裝,以便可以從Java調用它們。但是大多數C源代碼都使用命令行參數(argc和argv)並廣泛使用它們。有沒有什麼方法可以將我在Java中捕獲的字符串args []傳遞給C函數,並對C源文件進行非常小的更改?圍繞C主函數編寫JNI封裝
我相信作爲JNI包裝的一部分,我必須在C編寫一個由Java代碼調用的函數。
當然,您必須編寫由Java代碼調用的C函數。
如在Radiodef指出的答案中看到的那樣,該函數將收到jobjectarray
,因爲jni
中的java String[]
表示爲jobjectArray
。
在該函數中,您將不得不malloc一個C數組,用於存儲您的傳統main
函數所期望的所有char *指針的參數char **argv
。
您將在該數組中存儲malloced指針,以便能夠立即釋放JNI對象。你可能會避免使用malloc,但是需要將JNI資源存儲到另一個數組中以供進一步發佈,所以我認爲這不是一個好主意。
請記住,傳統主要函數的約定是第一個參數(索引0)是'程序名'。你將不得不僞造它。
void MyJNIFunction(JNIEnv *env, jobject object, jobjectArray stringArray) {
// Get the number of args
jsize ArgCount = (*env)->GetArrayLength(env, stringArray);
// malloc the array of char* to be passed to the legacy main
char ** argv = malloc(sizeof(char*)*(ArgCount+1)); // +1 for fake program name at index 0
argv[ 0 ] = "MyProgramName";
int i;
for (i = 0; i < ArgCount; ++i) {
jstring string = (jstring)((*env)->GetObjectArrayElement(env, stringArray, i));
const char *cstring = (*env)->GetStringUTFChars(env, string, 0);
argv[ i + 1 ] = strdup(cstring);
(*env)->ReleaseStringUTFChars(env, string, cstring);
(*env)->DeleteLocalRef(env, string);
}
// call the legacy "main" function
LegacyMain(ArgCount + 1, argv);
// cleanup
for(i = 0; i < ArgCount; ++i) free(argv[ i + 1 ]);
free(argv);
return;
}
使用'GetStringUTFChars'假定LegacyMain函數可以採用Java Unicode字符串的_modified_ UTF-8編碼。最好知道它所期望的編碼和字符集,並使用'String.getBytes(...)'在Java中轉換爲它。 –
@TomBlodget你是對的。不知道我是否必須更新。我的代碼在普通的舊式ASCII 7位參數中工作得很好嗎? – manuell
它看起來會,但我想不出任何使用完整的ASCII和只有ASCII的系統。程序參數通常是文件系統路徑。我想不出任何使用ASCII的文件系統。 –
[傳遞字符串數組從Java到C與JNI]的可能重複(http://stackoverflow.com/questions/5972207/passing-string-array-from-java-to-c-with-jni ) – Radiodef