Android native code crash
I have a test case where java is calling a simple routine in C with a couple of args and it returns a string and it works.
However, when I coded up my real code the same way it crashes with an "Invocation Target Exception". I then simplified it to just a call and return of a string and it still crashes.
One difference between the two cases is that one of the calls has 6 floating-point args, and the other one has 14 floating ars. The 6-arg one gets called first (a setup) and I get the exception.
Is there any practical limitation on number of args that can be in a call to native code? Or should I continue looking at my code for the problem elsewhere?
Sorry - I couldn't get the logcat to format as a comment so I'm posting it as an edit instead. Here's the logcat, any suggestion where I should look? What does "No implementation found" mean?
D/dalvikvm( 531): Added shared lib /data/data/com.kinyur.etold/lib/libgalib.so 0x405133e0
D/dalvikvm( 531): No JNI_OnLoad found in /data/data/com.kinyur.etold/lib/libgalib.so 0x405133e0, skipping init
W/dalvikvm( 531): No implementation found for native Lcom/kinyur/etold/NativeLib;.setup (FFFFFF)Ljava/lang/String;
D/AndroidRuntime( 531): Shutting down VM
W/dalvikvm( 531): threadid=1: thread exiting with uncaught exception (group=0x40015560)
E/Androi开发者_C百科dRuntime( 531): FATAL EXCEPTION: main
The routine is called with 6 floats and returns a String type. And the "setup" is the name of the routine I called when it crashed.
I'm not aware of any limitations of the number of arguments of a JNI method
Sorry for the distraction, I spent all day on this and found that the problem was just a stupid typo on my part, probably a copy-and-paste problem.
Interesting also that I had protected the native call with a try...catch block, but the program still crashed instead of getting an exception.
I had two problems. The first primary one was:
The decorated name of the routine in my .C file was wrong. In my test case that worked, I was using:
JNIEXPORT jstring JNICALL Java_com_example_atest_NativeLib_hello
and in my real case I wanted:
JNIEXPORT jstring JNICALL Java_com_kinyur_etold_NativeLib_doSetup
but what I had was:
JNIEXPORT jstring JNICALL Java_com_example_atest_NativeLib_doSetup
so I had cruft left over from when I copied the case that worked into the new one. I don't know how many times I looked at it today and didn't notice it. :-(
And interestingly enough, according to logcat, it seemed to link to the library OK and failed when it ran (using the routine name 'hello' instead of 'doSetup'):
D/dalvikvm( 460): Trying to load lib /data/data/com.kinyur.etold/lib/libgalib.so 0x40515840
D/dalvikvm( 460): Added shared lib /data/data/com.kinyur.etold/lib/libgalib.so0x40515840
D/dalvikvm( 460): No JNI_OnLoad found in /data/data/com.kinyur.etold/lib/libgalib.so 0x40515840, skipping init
W/dalvikvm( 460): No implementation found for native Lcom/kinyur/etold/NativeLib;.hello ()Ljava/lang/String;
D/AndroidRuntime( 460): Shutting down VM
W/dalvikvm( 460): threadid=1: thread exiting with uncaught exception (group=0x40015560)
E/AndroidRuntime( 460): FATAL EXCEPTION: main
E/AndroidRuntime( 460): java.lang.UnsatisfiedLinkError: hello
E/AndroidRuntime( 460): at com.kinyur.etold.NativeLib.hello(Native Method)
E/AndroidRuntime( 460): at com.kinyur.etold.ComFields.<init>(ComFields.java:33)
E/AndroidRuntime( 460): at com.kinyur.etold.EtMain.onCreate(EtMain.java:28)
E/AndroidRuntime( 460): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
The SECOND problem I found while hunting for the first one was that I was incorrectly returning a string in the C routine.
I had:
char* aString = "1234";
return aString;
What was needed was:
return (*env)->NewStringUTF(env, aString);
精彩评论