Android 原生代码崩溃

发布于 2024-12-04 08:35:57 字数 936 浏览 1 评论 0原文

我有一个测试用例,其中 java 使用几个参数调用 C 中的一个简单例程,它返回一个字符串并且它可以工作。

然而,当我以同样的方式编写真实代码时,它会因“调用目标异常”而崩溃。然后我将其简化为仅调用并返回字符串,但它仍然崩溃。

两种情况之间的一个区别是,其中一个调用有 6 个浮点参数,而另一种调用有 14 个浮点参数。 6-arg 的一个首先被调用(一个设置),我得到了异常。

对本机代码的调用中可以使用的参数数量是否有任何实际限制?或者我应该继续在其他地方查看我的代码是否存在问题?

抱歉 - 我无法将 logcat 格式化为评论,因此我将其作为编辑发布。这是 logcat,有什么建议我应该看哪里吗? “未找到实施”是什么意思?

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/AndroidRuntime(  531): FATAL EXCEPTION: main

该例程使用 6 个浮点数调用并返回 String 类型。 “设置”是我在崩溃时调用的例程的名称。

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/AndroidRuntime(  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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

满意归宿 2024-12-11 08:35:57

我不知道 JNI 方法的参数数量有任何限制

I'm not aware of any limitations of the number of arguments of a JNI method

破晓 2024-12-11 08:35:57

抱歉打扰了,我花了一整天的时间来解决这个问题,发现这个问题只是我的一个愚蠢的打字错误,可能是一个复制粘贴问题。

有趣的是,我使用 try...catch 块保护了本机调用,但程序仍然崩溃而不是出现异常。

我有两个问题。第一个主要问题是:

我的 .C 文件中例程的修饰名称是错误的。在我有效的测试案例中,我使用的是:

JNIEXPORT jstring JNICALL Java_com_example_atest_NativeLib_hello

在我的真实案例中,我想要:

JNIEXPORT jstring JNICALL Java_com_kinyur_etold_NativeLib_doSetup

但我所拥有的是:

JNIEXPORT jstring JNICALL Java_com_example_atest_NativeLib_doSetup

所以当我将适用于新案例的案例复制到新案例中时,我留下了一些残渣。今天不知道看了多少遍了,竟然没有注意到。 :-(

有趣的是,根据 logcat,它似乎可以正常链接到库,但在运行时失败(使用例程名称“hello”而不是“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)

我在寻找第一个问题时发现的第二个问题是我在 C 例程中错误地返回了一个字符串

char* aString = "1234";
return aString;

需要的是:

return (*env)->NewStringUTF(env, aString);

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文