【问题标题】:jni starter questionjni入门问题
【发布时间】:2011-02-10 19:53:39
【问题描述】:


我开始研究 JNI,据我了解,如果加载的 dll 出现问题,jvm 可能会当场终止。
IE。该过程无法受到保护,例如就像捕获异常时一样。
因此,如果我的理解是正确的,我的问题是在使用 jni 时是否有针对这种情况的标准方法/模式。
或者换一种说法,使用 jni 的流程是否旨在避免这些问题? 还是预计不会出现此类问题?

谢谢。

【问题讨论】:

    标签: java c dll java-native-interface native-code


    【解决方案1】:

    是的,JVM 将终止,这也是 JNI 代码很难调试的原因之一。如果您使用的是 C++ 代码,您可以使用异常,然后将它们映射到 Java 异常,这至少可以为您提供一定程度的安全性,但对诸如错误的内存访问等问题没有帮助。

    从架构的角度来看,我建议尽可能将您的代码与 JNI 分离。创建一个完全可从 C++/C 测试的类/过程结构,让 JNI 代码只做所有的转换工作。如果 JVM 然后崩溃,您至少知道必须查看的位置。

    【讨论】:

    • 我想到的第一个想法是放置帖子,是生成一个新进程来访问 dll。这样原始进程就可以生存。但我不确定这是否用作一种方法
    • 嗯,但在这种情况下,您不妨根本不使用 JNI,而改用另一种进程间通信方式。如果速度是最大的问题,我只会使用 JNI(然后将它放在自己的进程中是没有意义的)。这是速度和安全性之间的权衡。
    【解决方案2】:

    原理与任何多线程 C 应用程序没有什么不同:

    1. 始终彻底检查您的所有输入。
    2. 始终释放您分配的临时内存。
    3. 确保您的函数是可重入的。
    4. 不要依赖未定义的行为。

    Java 虚拟机不会为您的本机代码提供额外的保护,如果它失败或泄漏,您的虚拟机将失败或泄漏。

    【讨论】:

    • @Daff:我想到的第一个想法是放置帖子,是产生一个新进程来访问 dll。这样原始进程就可以存活。但我不确定这是否用作一种方法
    • @user384706 生成一个新进程并非没有风险,而且对于大多数用途来说速度慢得让人无法接受。另外,如果您要启动一个外部进程,为什么不从纯 Java 开始呢?
    • 我认为本机代码将用于无法在 java 中完成的特定情况的想法,原始进程产生一个新进程来访问 dll,即任何结果/消息都是发送到父进程。如果发生某些事情,第二个进程会死掉,但可以执行更多功能(访问 dll)的原始进程只是其中的一部分,它仍然会存在。我不确定这是否是一种使用的方法。可能是太多了?
    • @user384706 听起来确实有点过分,但我不知道具体情况。将其他进程编译成 exe 并从 Java 启动它不是更容易吗?
    【解决方案3】:

    您可以在 JNI 库中进行与其他任何内容完全相同的错误处理范围。

    您可以使用 try/catch。如果您在 Windows 上,则可以使用 SEH。如果你在 Linux 上,你可以调用 sigaction。

    不过,如果您搞砸了并且有一个 SIGSEGV,那么无论您是否尝试捕获该信号,您的 JVM 都可能会失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多