Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.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_C_Java Native Interface - Fatal编程技术网

运行一段存储在Java字符串中的C代码

运行一段存储在Java字符串中的C代码,java,c,java-native-interface,Java,C,Java Native Interface,我这里有一个相当有趣的场景。假设我有一段C代码存储在Java字符串中。我需要在我的Java程序中自己运行这段代码 案例1 我想我应该做的是 在主窗口中创建本机字段 将sCode写入文件 使用Java中的Exceulte shell命令编译c代码。 从java调用本机方法 案例2 我正在考虑执行上述过程,因为如果源代码是预定义的,我知道如何使用JNI来执行此操作 class Main{ static { System.loadLibrary("Main"); //

我这里有一个相当有趣的场景。假设我有一段C代码存储在Java字符串中。我需要在我的Java程序中自己运行这段代码

案例1

我想我应该做的是

在主窗口中创建本机字段 将sCode写入文件 使用Java中的Exceulte shell命令编译c代码。 从java调用本机方法 案例2

我正在考虑执行上述过程,因为如果源代码是预定义的,我知道如何使用JNI来执行此操作

 class Main{

      static {
        System.loadLibrary("Main"); // Load native library at runtime
      }

      private native void sayHello();

      public static void main(String[] args) {
        new Main().sayHello();
      }

    }
对于预先编写的C代码。我们所做的是

使用javac Main.java编译java类 为C库生成头文件。javah-jnimain 通过编写c代码来完成Main.c 使用gcc-share-I/path/to/jni-I/path/to/jni_md-o Main.so编译C代码 干管。爪哇岛 有人能告诉我在案例1中我是否走上了正确的道路吗?还是有更好的方法

**注意:这里的关键点是,我只允许编译java代码一次。一开始**

编辑:在检查了@Dúthomhas的评论和回答之后,我想我应该再解释一件事。我之所以这样做是为了一个机器学习项目。已经确定数值计算部分存在瓶颈,使用C作为上述方法值得尝试。所以安全问题现在已经不存在了。我们只需要做一个实验

无答案回答:不要那样做

你要求做的是一个非常糟糕的主意,原因有以下两个:

它可能会打开严重的安全漏洞 实施的成本可能大于收益 要求嵌入一种完全不同的语言意味着添加和链接一个库和许多代码来同步库,再加上执行静态分析和沙箱代码的代码。换句话说,您要求在已有的基础上实现整个语言

可以说,无论如何,C是基本系统,JVM甚至可以在其上实现,但这不是重点。问题不在于C库,而在于C编译器/解释器,就简单的解释性编程语言而言,它是一个相当复杂的代码库

建议:使用Java

ToolProvider类专门为您提供Java代码的动态编译。看一看

确保使用SecurityManager类正确地对代码进行沙箱处理。如果可能的话,在一个单独的、受限的JVM中运行它

建议:使用JavaScript/ECMAScript

ScriptEngine类正是为此而设计的。再一次,谷歌到处寻找例子。再说一次,别忘了安全

建议:使用现有的图书馆

但是我真的想/必须用C

唉。使用C是可能的,但难度很大。在谷歌上搜索“嵌入式c解释器”,寻找可以集成到源代码中的小型c解释器。祝你好运

让我澄清你的两个案例

案例1指的是在进程外运行C程序。这不是大多数人认为从java调用本地方法的原因。您不能在Main中创建本机字段。实际上,Java没有本机字段,只有本机方法。但在案例1中,您也不使用本机方法。只要运行时环境中有编译器,就可以编译和运行任何用C或任何其他语言编写的程序。为此,您可以使用shell命令Runtime.exec来编译和运行程序。可以按照Runtime.exec中的指定在“命令行”上传递C程序的参数。它可以通过您选择的任何IPC与Java进程通信。通常,我们只是使用管道来读取子进程的标准输出

案例2使用JNIJava本机接口在进程中运行本机代码。您在这里描述的流程是正确的,但是您可以修改它以使用在运行时构建的共享库。首先,删除本机方法,并将库加载到单独的类中。确保类加载器仅在主类使用与案例1相同的Runtime.exec运行gcc-o libMain.so命令后加载此类。这样,静态构造函数将加载新构建的库

在这两种情况下,都不需要重新编译Java。您不需要运行javah来构建libMain.so-这只是一个方便的步骤,以确保C头与Java类同步。但是在您的情况下,Java类不会改变——因此本机方法签名也不会改变


请注意,案例1更容易,特别是当您必须运行不同的编译C“字符串”时,但如果您必须多次调用本机方法,案例2可能会提供更好的性能。

您试图解决的问题是什么?对于非答案,此答案包含了关于为什么应该执行上述操作的非常好的见解 不能这样做。请投赞成票。我不能接受这个答案,因为我还没有收到原始问题的答案。好吧,我不想嵌入整个语言。我只想将一个数组从Java传递到C并接收一个数组。我的程序应该为Java字符串中的一个动态C函数工作。
 class Main{

      static {
        System.loadLibrary("Main"); // Load native library at runtime
      }

      private native void sayHello();

      public static void main(String[] args) {
        new Main().sayHello();
      }

    }