gpt4 book ai didi

java - 驱动程序回调中 JNI 调用失败

转载 作者:行者123 更新时间:2023-11-30 06:36:35 28 4
gpt4 key购买 nike

我正在开发一个与硬件设备交互的应用程序。使用硬件官方应用程序提供的 dll 文件,我初始化设备并注册一些函数作为回调,以便在某些用户交互时调用。在这个回调函数中,我想调用一个Java函数来传输数据。但是,整个应用程序仅在回调中的此调用处退出,没有任何错误日志:

jclass cls = env->FindClass("java/lang/String");

如果在 Java 直接调用的函数中执行相同的调用,则该调用会起作用。这种行为的原因是什么?调用 JNI 与设备驱动程序调用有何不同?如有任何帮助,我们将不胜感激。

编辑:我尝试了 Vernee 的建议并尝试将驱动程序线程附加到 JVM,但是行为没有改变。此外,我丢失了 printf 输出,不幸的是,这是我调试 JNI 端的唯一选择。它们在附加操作之前工作,但之后停止工作。

最佳答案

如果您在Windows上进行开发,我强烈建议您使用Visual Studio来调试C代码。您可以启动您的java程序并在System.load上放置一个断点,当Java程序在此时停止时,转到Visual studio并从工具>附加进程中,这样您就可以在C代码中放置的断点处停止。之后只需恢复java代码即可。从 C 线程调用 java 方法需要一些准备工作:

1- 缓存 JVM 对象

JavaVM * javaVm;
(*jenv)->GetJavaVM(jenv, &javaVm);

2- 缓存包含 java 回调方法的 Class 的 Class 对象。

clazz = (*jenv)->NewGlobalRef(jenv, (*jenv)->FindClass(jenv, "com/something/somepackage/SomeClass"));

3-如果您正在调用实例方法,您还需要cahce被调用的实例

callback = (*jenv)->NewGlobalRef(jenv, callbackInstance);

4- 将 native 线程附加到虚拟机(当您需要调用java方法时)

JNIEnv * jenv;
int errorCode = (*j_javaVm)->AttachCurrentThread(j_javaVm, (void**) &jenv, NULL);

5-获取您需要调用的方法ID(当您需要调用java方法时)

jmethodID methodID = (*jenv)->GetMethodID(jenv, cachedhandlerClass, "methodNameHere", "methodSignetureHere");

6-进行方法调用

(*jenv)->CallVoidMethod(jenv, cachedCallbackInstance, methodID, param1, param2,....);

7- 分离 native 线程

(*j_javaVm)->DetachCurrentThread(j_javaVm);

步骤1,2和3需要java环境,它们可以在JNI_OnLoad方法中完成,也可以在本地Java方法的实现中完成。

关于java - 驱动程序回调中 JNI 调用失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45130106/

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