JNI调用C中fprintf生成乱码文件名问题求助
Got it, let's cut to the chase—your problem is a classic JNI string handling mistake! You're directly treating a Java String as a native C const char* in your JNI method, which causes garbage characters because Java strings use UTF-16 encoding, while C expects a UTF-8 or system-native encoded byte array. The file content works fine because that logic doesn't depend on the broken filename parsing.
The Fix: Properly Convert Java Strings in JNI
You need to use JNI's built-in functions to safely convert the jstring (Java's string type in JNI) to a C-style string. Here's how to update your code:
First, modify your JNI method signature and implementation:
JNIEXPORT void JNICALL Java_jrapl_AsyncEnergyMonitorCSide_writeToFileFromC(JNIEnv* env, jclass jcls, jstring j_filepath) { // Convert Java UTF-16 string to UTF-8 C string const char* filepath = (*env)->GetStringUTFChars(env, j_filepath, NULL); if (filepath == NULL) { // Handle allocation failure (rare, but good practice) return; } // Call your existing write logic with the valid C string writeToFile(monitor, filepath); // Critical: Release the string to avoid memory leaks! (*env)->ReleaseStringUTFChars(env, j_filepath, filepath); }
Keep your Java code unchanged—no adjustments needed here:
private native static void writeToFileFromC(String filePath); public void writeToFile(String filePath) { writeToFileFromC(filePath); }
Why This Works
- Java strings are stored as UTF-16, which can't be directly interpreted as a C
const char*(which expects UTF-8 or system-native bytes). Your original code was reading UTF-16 bytes as if they were UTF-8, hence the garbage filename. GetStringUTFCharsconverts the Java string to a UTF-8 encoded C string, which is fully compatible with standard C file operations likefopen.- Always call
ReleaseStringUTFCharsafter you're done with the C string—JNI allocates memory for this conversion, and forgetting to release it will cause memory leaks over repeated calls.
Bonus Notes
- If you need to handle filenames with system-specific non-ASCII characters,
GetStringUTFCharsis still the safest default since UTF-8 is widely supported across modern operating systems. - You don't have to abandon your efficient C-side file writing! This fix only corrects the filename passing issue—your original logic of writing data directly from C remains intact, keeping the performance advantage you wanted.
内容的提问来源于stack exchange,提问作者aservet1

