C11编写JNI代码时严格合规堆上对象创建的参数类型问询
NewObject Arguments Great question about sticking strictly to C11 standards when working with JNI's NewObject! Let’s break this down clearly to make your code fully compliant.
First, let’s anchor on the key details:
- Your Java
Eventconstructor takes anintand aString, which maps to the JNI signature(ILjava/lang/String;)V. - Per C standard 6.5.2.2(p7), arguments passed to variadic functions (like
NewObject, which uses...) must be explicitly cast to the exact type the function expects—no implicit conversions are guaranteed here, so cutting corners could lead to undefined behavior.
What Types Should You Cast To?
Each variadic argument needs to match the JNI type that corresponds directly to your Java constructor’s parameters:
- For the Java
intparameter: Usejint. This is the JNI-defined type that maps 1:1 to Java’sint. Your current cast(jint) 0is already correct and compliant. Even ifintandjinthave the same width on your platform, the explicit cast is required to meet strict C11 rules. - For the Java
Stringparameter: Usejstring. Whilejstringis technically a typedef forjobject, the constructor’s signature explicitly expects aLjava/lang/String;type. Casting tojstring(instead ofjobject) makes your code align perfectly with the expected type, which is the strictest, most compliant choice. Your current(jobject) NULLwill run in practice, but it’s better to match the exact type the JNI call expects.
Corrected Compliant Code
Here’s the adjusted code that checks all boxes for C11 and JNI standards:
jclass event_class = (*env)->FindClass(env, "f/q/c/n/Event"); jmethodID ctor = (*env)->GetMethodID( env, event_class, "<init>", "(ILjava/lang/String;)V" ); jobject array_element = (*env)->NewObject( env, event_class, ctor, (jint) 0, // Explicit cast to jint (matches Java int) (jstring) NULL // Explicit cast to jstring (matches Java String) );
Why This Matters
C’s variadic argument handling doesn’t do type checking or implicit conversions beyond basic default promotions (like char to int). By explicitly casting to the JNI types NewObject expects, you eliminate the risk of undefined behavior—especially important if you’re targeting multiple platforms where native type sizes (like int) might differ from JNI types (like jint).
内容的提问来源于stack exchange,提问作者Some Name

