gpt4 book ai didi

android - 使用 NDK 时如何正确命名原生函数

转载 作者:行者123 更新时间:2023-11-29 14:23:23 26 4
gpt4 key购买 nike

我正在尝试运行我的应用程序,但每当我调用 native 函数时,它都会给我一个错误并且程序崩溃。我确信这与我在 Java 或 C 中命名某物的方式有关。

这是我对 Java 函数的调用:

package my.commander;

public class RelayAPIModel {

public static class NativeCalls {

static {
System.loadLibrary( "RelayAPI");
}

public native static byte InitRelayJava();

public native static void FreeRelayJava();
}

.c 文件中的函数如下:

void Java_my_commander_RelayAPIModel_FreeRelayJava( JNIEnv * env, jobject this ) {
RelayAPI_DataValid = 0;
RelayAPI_SetBaud = 0;
RelayAPI_get = 0;
RelayAPI_put = 0;
RelayAPI_flush = 0;
RelayAPI_delay = 0;
RelayAPI_initilized = 0;
}


BYTE Java_my_commander_RelayAPIModel_InitRelayJava( JNIEnv *env, jobject obj ) {
...
...
}

它们在 .h 文件中:

void Java_my_commander_RelayAPIModel_FreeRelayJava( JNIEnv * env, jobject obj );

BYTE Java_my_commander_RelayAPIModel_InitRelayJava( JNIEnv *env, jobject obj );

这是我的 LogCat:

08-01 09:58:21.933: E/AndroidRuntime(17170): FATAL EXCEPTION: main
08-01 09:58:21.933: E/AndroidRuntime(17170): java.lang.UnsatisfiedLinkError: InitRelayJava
08-01 09:58:21.933: E/AndroidRuntime(17170): at my.eti.commander.RelayAPIModel$NativeCalls.InitRelayJava(Native Method)
08-01 09:58:21.933: E/AndroidRuntime(17170): at my.eti.commander.MainMenu.initMain(MainMenu.java:241)
08-01 09:58:21.933: E/AndroidRuntime(17170): at my.eti.commander.MainMenu.onCreate(MainMenu.java:81)
08-01 09:58:21.933: E/AndroidRuntime(17170): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-01 09:58:21.933: E/AndroidRuntime(17170): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-01 09:58:21.933: E/AndroidRuntime(17170): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-01 09:58:21.933: E/AndroidRuntime(17170): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-01 09:58:21.933: E/AndroidRuntime(17170): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08-01 09:58:21.933: E/AndroidRuntime(17170): at android.os.Handler.dispatchMessage(Handler.java:99)
08-01 09:58:21.933: E/AndroidRuntime(17170): at android.os.Looper.loop(Looper.java:130)
08-01 09:58:21.933: E/AndroidRuntime(17170): at android.app.ActivityThread.main(ActivityThread.java:3683)
08-01 09:58:21.933: E/AndroidRuntime(17170): at java.lang.reflect.Method.invokeNative(Native Method)
08-01 09:58:21.933: E/AndroidRuntime(17170): at java.lang.reflect.Method.invoke(Method.java:507)
08-01 09:58:21.933: E/AndroidRuntime(17170): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-01 09:58:21.933: E/AndroidRuntime(17170): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-01 09:58:21.933: E/AndroidRuntime(17170): at dalvik.system.NativeStart.main(Native Method)

现在我想澄清一下,我已经尝试将 C 方法名称更改为 Java_my_commander_RelayAPIModel_NativeCalls_FreeRelayJavaJava_my_commander_RelayAPIModel_NativeCalls_InitRelayJava。应用程序仍然无法启动,这是 LogCat:

08-01 11:22:10.735: E/AndroidRuntime(17441): FATAL EXCEPTION: main
08-01 11:22:10.735: E/AndroidRuntime(17441): java.lang.UnsatisfiedLinkError: InitRelayJava
08-01 11:22:10.735: E/AndroidRuntime(17441): at my.eti.commander.RelayAPIModel$NativeCalls.InitRelayJava(Native Method)
08-01 11:22:10.735: E/AndroidRuntime(17441): at my.eti.commander.MainMenu.initMain(MainMenu.java:241)
08-01 11:22:10.735: E/AndroidRuntime(17441): at my.eti.commander.MainMenu.onCreate(MainMenu.java:81)
08-01 11:22:10.735: E/AndroidRuntime(17441): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-01 11:22:10.735: E/AndroidRuntime(17441): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-01 11:22:10.735: E/AndroidRuntime(17441): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-01 11:22:10.735: E/AndroidRuntime(17441): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-01 11:22:10.735: E/AndroidRuntime(17441): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08-01 11:22:10.735: E/AndroidRuntime(17441): at android.os.Handler.dispatchMessage(Handler.java:99)
08-01 11:22:10.735: E/AndroidRuntime(17441): at android.os.Looper.loop(Looper.java:130)
08-01 11:22:10.735: E/AndroidRuntime(17441): at android.app.ActivityThread.main(ActivityThread.java:3683)
08-01 11:22:10.735: E/AndroidRuntime(17441): at java.lang.reflect.Method.invokeNative(Native Method)
08-01 11:22:10.735: E/AndroidRuntime(17441): at java.lang.reflect.Method.invoke(Method.java:507)
08-01 11:22:10.735: E/AndroidRuntime(17441): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-01 11:22:10.735: E/AndroidRuntime(17441): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-01 11:22:10.735: E/AndroidRuntime(17441): at dalvik.system.NativeStart.main(Native Method)


现在,我认为错误出在上面的代码中。如果你们都认为它没有问题,我将在此处添加更多信息以防万一问题出在其他地方。

我正在创建的这个应用程序使用上面的函数来调用一个已经使用了一段时间的库。该库以前用于调用 Palm Pilot 程序中的函数,该程序利用了 Palm 的蓝牙功能。由于 Android 设备具有不同的蓝牙库/功能,我将代码添加到 native 库以调用 BACK 到 java 代码,以访问 Android 设备的蓝牙功能。我不想在这里发布与此相关的所有代码,但如果有人认为需要发布它,我会发布。

最佳答案

错误消息说它位于:

my.eti.commander.RelayAPIModel$NativeCalls.InitRelayJava (Native Method)

因此请确保:

  • native 方法声明确实在 RelayAPIModel 类中,不包括 RelayAPIModel.NativeCalls 嵌套类。
  • Java 端的包名称是 my.commander 而不是 my.eti.commander

编辑:或者您可以在 C 端修复它。如果你想在嵌套类中创建本地方法,它的正确名称是:

Java_my_commander_RelayAPIModel_00024NativeCalls_InitRelayJava()

00024是$字符的代码,是Java内部的嵌套类分隔符。此外,第二个参数 (jobject Obj) 的含义将有所不同 - 而不是 RelayAPIModelthis 指针/类指针,它将成为 RelayAPIModel.NativeCalls 的那个。您将无法使用它来解析/调用 RelayAPIModel 中的方法。

关于android - 使用 NDK 时如何正确命名原生函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11762654/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com