从 Java Swing GUI 调用本机 C 代码

发布于 2024-12-11 08:11:55 字数 1826 浏览 0 评论 0原文

我正在尝试读取和写入并行端口,我用 C 实现了写入和读取,现在我想将该代码导入到 java GUI 应用程序中。 我设法将 C .so 文件包含到 java 项目中,并且当直接在 Java 解决方案 main() 方法中调用函数时,它们工作得很好。

我尝试在按下按钮时调用本机函数,但它不起作用,应用程序崩溃了。我以 root 身份运行应用程序,需要 root 权限才能更改和读取并行端口值。

我如何尝试调用本机函数:

 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
       try
       {
           int portNR=Integer.parseInt(jTextField1.getText());
           int value=Integer.parseInt(jTextField2.getText());
        ParalellComanderApp.setPort(portNR,value );
       }
       catch (Exception e)
       {
           System.err.println(e.getMessage());
       }
    }

C 中的本机函数:

JNIEXPORT void JNICALL Java_paralellcomander_ParalellComanderApp_setPort
  (JNIEnv *env, jobject obj, jint port, jint value)
{
     outb(value,MAIN_PORT+port); 
     printf("Setting port %d to value %d\n",port,value);
}

崩溃消息:

    A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f00adaf9833, pid=6516, tid=139640785835776
#
# JRE version: 6.0_23-b23
# Java VM: OpenJDK 64-Bit Server VM (20.0-b11 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea6 1.11pre
# Distribution: Ubuntu oneiric (development branch), package 6b23~pre10-0ubuntu5
# Problematic frame:
# C  [libAccessParalel.so+0x833]  inb+0x17
#
# An error report file with more information is saved as:
# /home/bari/NetBeansProjects/ParalellComander/dist/hs_err_pid6516.log
#
# If you would like to submit a bug report, please include
# instructions how to reproduce the bug and visit:
#   https://bugs.launchpad.net/ubuntu/+source/openjdk-6/
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.

抱歉发了这么长的帖子。 有人可以帮助我吗?

I am trying to read and write to the parallel port, I implemented the writing and reading in C, now I want to import that code into a java GUI application.
I managed to include the C .so file into the java project and when calling the functions directly in the Java solutions main() method they work just fine.

I tried to call the native functions when a button is pressed, but it won't work, the application crashes. I am running the application as root, root priviledge is needed to change and read the parallel ports values.

How I am trying to call the native function:

 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
       try
       {
           int portNR=Integer.parseInt(jTextField1.getText());
           int value=Integer.parseInt(jTextField2.getText());
        ParalellComanderApp.setPort(portNR,value );
       }
       catch (Exception e)
       {
           System.err.println(e.getMessage());
       }
    }

The Native function in C:

JNIEXPORT void JNICALL Java_paralellcomander_ParalellComanderApp_setPort
  (JNIEnv *env, jobject obj, jint port, jint value)
{
     outb(value,MAIN_PORT+port); 
     printf("Setting port %d to value %d\n",port,value);
}

Crash message:

    A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f00adaf9833, pid=6516, tid=139640785835776
#
# JRE version: 6.0_23-b23
# Java VM: OpenJDK 64-Bit Server VM (20.0-b11 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea6 1.11pre
# Distribution: Ubuntu oneiric (development branch), package 6b23~pre10-0ubuntu5
# Problematic frame:
# C  [libAccessParalel.so+0x833]  inb+0x17
#
# An error report file with more information is saved as:
# /home/bari/NetBeansProjects/ParalellComander/dist/hs_err_pid6516.log
#
# If you would like to submit a bug report, please include
# instructions how to reproduce the bug and visit:
#   https://bugs.launchpad.net/ubuntu/+source/openjdk-6/
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.

Sorry for the long post.
Can anybody help me?

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

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

发布评论

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

评论(2

漫雪独思 2024-12-18 08:11:55

我不会使用 JNI 并以 root 身份运行 GUI,而是将 C 部分制作成一个独立的程序(以最低限度的特权运行 - 即它绑定到并行端口,然后撤销所有其他特权),该程序与 Java 对话通过网络套接字的应用程序。这样,您就可以更好地控制面向最终用户的部分和具有提升权限的部分之间传递的内容,并且不易受到攻击。调试和测试也会更容易,因为您可以使用 telnet 或 netcat 测试与 C 程序的网络通信,甚至无需涉及 GUI 部分。

Rather than using JNI and running your GUI as root, I would make the C part into a stand alone program (that runs with the bare minimum privileges - i.e. it binds to the parallel port and then revokes all other privileges) which talks to the Java app over a network socket. That way you have more control over what passes between the part that faces the end user and the part that has elevated privileges, and are less vulnerable to attack. It would also be easier to debug and test, because you can test the network communication to the C program using telnet or netcat without even involving the GUI part.

半﹌身腐败 2024-12-18 08:11:55

我认为没有必要创建一个完全独立的程序,但是您应该创建一个
接口类,确保端口设置正确,并且序列化 jni 调用,而不是直接从 GUI 敲击硬件。

除此之外,编写一个好的 JUnit 测试,并研究更多有关并行端口编程的知识。
(http://as6edriver.sourceforge.net/Parallel-Port-Programming-HOWTO/accessing.html)

我不认为你有来自jvm的核心转储?您是否阅读过生成的日志?

顺便说一句,我认为 JNA 比 JNI 使用起来稍微不那么痛苦,尽管你的问题不会通过更改为 JNA 来解决......

I don't think it's necessary to create a totally stand-alone program, but you should create an
interface class, that makes sure that the port is setup properly, and also serialize the jni-calls, rather than banging on the hardware directly from the gui.

Other than that, write a good JUnit test, and research some more about parallel port programming.
(http://as6edriver.sourceforge.net/Parallel-Port-Programming-HOWTO/accessing.html)

I don't suppose you have a core dump from the jvm? Have you read the logs that were generated?

Btw, I think JNA is slightly less of a pain to work with than JNI, although your problem won't be solved by changing to JNA...

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