Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JAVA中从框架调用C代码_Java_Swing_Java Native Interface - Fatal编程技术网

在JAVA中从框架调用C代码

在JAVA中从框架调用C代码,java,swing,java-native-interface,Java,Swing,Java Native Interface,我对java编程非常陌生,因此,如果这听起来像一个愚蠢的问题,我会提前道歉 我使用JNI通过创建Swing JFrame并显示它来调用C代码。代码相当简单,如果我将框架可见性设置为false(即调用“hello”方法),Java代码工作正常,而当我将框架可见性设置为true时,什么都不会发生(即不调用“hello”方法) Test.java public class Test extends JFrame { private JPanel contentPane; public

我对java编程非常陌生,因此,如果这听起来像一个愚蠢的问题,我会提前道歉

我使用JNI通过创建Swing JFrame并显示它来调用C代码。代码相当简单,如果我将框架可见性设置为false(即调用“hello”方法),Java代码工作正常,而当我将框架可见性设置为true时,什么都不会发生(即不调用“hello”方法)

Test.java

public class Test extends JFrame {

    private JPanel contentPane;
    public static Container root;

    /**
     * Launch the application.
     */

     public static void main(String[] args) {

        try {
            Test frame = new Test();

            new JNIServer().hello("world");  // where hello is native method
            frame.setVisible(true);

        } catch (Exception e) {
            e.printStackTrace();        
        }
    }       
}
JNIServer.java

public class JNIServer{

    public native void hello(String name);  

    static {  
         System.out.println("Inload library");
         System.loadLibrary("JNI_Lib");     
    }  
}
如前所述,您可以尝试使用单独的线程。我还会尝试添加一些println语句,以查明问题的原因

为了重现您的问题,我在Ubuntu 14.04 64位上测试了Java SE 1.8.0_66-b17(Java-version)和gcc(Ubuntu 4.8.4-2ubuntu1~14.04)4.8.4(gcc-version)

为了简化一些,我没有将
String
参数传递给
hello
方法/函数,暂时跳过该转换。以下是我用来测试的源文件:

// Test.java

import java.awt.Container;
import javax.swing.*;

public class Test extends JFrame {
    private JPanel contentPane;
    public static Container root;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        try {
            Test frame = new Test();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            frame.callNativeFunction();

            System.out.println("Test.main - before setting frame visible");
            frame.setVisible(true);
            System.out.println("Test.main - after setting frame visible");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void callNativeFunction() {
        Thread nativeFunctionThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Test.run - before calling hello.");
                new JNIServer().hello();  // where hello is native method
                System.out.println("Test.run - after calling hello.");
            }
        });

        nativeFunctionThread.start();
    }
}


// JNIServer.java

public class JNIServer {
    public native void hello();

    static {  
        System.out.println("Inload library");
        System.loadLibrary("JNI_Lib");
    }  
}


// JNIServer.h (generated)

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNIServer */

#ifndef _Included_JNIServer
#define _Included_JNIServer
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JNIServer
 * Method:    hello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JNIServer_hello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


// JNI_Lib.c

#include <jni.h>
#include <stdio.h>

JNIEXPORT void JNICALL Java_JNIServer_hello(JNIEnv * environment,
                                            jobject java_object) {
    printf("Hello from C!\n");
}
这是
java-Djava.library.path=的输出。测试
命令:

Test.main - before setting frame visible
Test.run - before calling hello.
Inload library
Hello from C!
Test.run - after calling hello.
Test.main - after setting frame visible
备受期待的“来自C的你好!”被打印出来了。可以看到一个(非常小的)框架。(可以使用
JFrame.setBounds
方法调整框架的大小和位置。)

编辑:使用Eclipse

虽然应该可以有一个组合的,但我建议从一个较小的步骤开始:使用两个单独的Eclipse项目(或者甚至更小:创建一个Java项目,该项目引用您的CLI C项目创建的库)。如果这是可行的,您可以在一个组合的Eclipse项目上工作

上面的CLI示例的
java.library.path
指向包含libJNI_Lib.so文件的目录。对于Eclipse中的Java项目,您可以选择运行|运行配置。。。菜单,如有必要,在左侧面板中选择Java项目,在右侧面板中选择Arguments选项卡,并在VM参数中添加“-Djava.library.path=。”(不带引号)。例如,请参见“运行配置”对话框的屏幕截图:


这是您的完整计划吗?JNI_Lib看起来像什么?请注意,在实际的程序中,您应该更加注意线程,确保Swing代码在Swing事件线程上启动,并且本机代码在其自己的线程中运行。我没有发布C代码,否则就是这样。这不是一个完整的程序,也不是一个完整的问题。@Alex。。我没有发布C文件,因为我试图在其中打印一些消息,以确保我能够从中访问C代码java@Freek.. 本教程与我的问题无关。我重复我的问题:我想使用GUI从Java到JNI访问C代码。您使用哪个版本的Java JDK和哪个C编译器?你在什么操作系统上运行?我使用JDK1.8、gcc编译器和ubuntu作为操作系统。我也在linuxmint上试用过。关闭Swing应用程序的建议:调用
frame.setDefaultCloseOperation(JFrame.EXIT_on_CLOSE)创建帧后。这将确保在关闭框架时关闭程序。谢谢您的建议。这对我很有帮助,因为当我合上相框时,“Hello from C”消息被打印出来了。但我的座右铭没有实现。我也尝试过你建议的代码,但仍然面临同样的问题。我没有得到和你一样的结果。“来自C的Hello没有同时打印”您能将您的输出添加到问题中吗?对我来说,“Hello from C!”消息是在框架可见之前(以及在我关闭框架之前)打印的。
Test.main - before setting frame visible
Test.run - before calling hello.
Inload library
Hello from C!
Test.run - after calling hello.
Test.main - after setting frame visible