将Java嵌入到C ++应用程序中?

时间:2011-09-21 20:39:34

标签: java c++ java-native-interface embed

我得到了一个用C ++编写的应用程序,我可以通过在C ++中编写插件来扩展应用程序功能。

我基本上想要做的是将Java嵌入到这个应用程序中。这已经用Python完成了(不是由我完成的)。

我读了一些关于JNI的内容,但总是有一个使用Java类的完整程序的语音。

我想做的是,使用Java中的C ++类来与应用程序进行交互 在这种情况下,它是一个3D应用程序,称为Cinema 4D。

有没有办法在应用程序运行时(使用某种脚本语言)使用JNI或类似的东西编译和评估Java代码?

嵌入完成后的虚构代码示例:

import c4d.documents.*;

class Main {
  public static void main() {
    BaseDocument doc = GetActiveDocument();
    BaseObject op = doc.GetActiveObject();
    if (op != null) {
      op.Remove();
    }
  }
}

此代码应与Cinema 4D交互以删除所选对象。

6 个答案:

答案 0 :(得分:41)

您可以在应用程序中嵌入JVM。 Oracle的official reference book有更多细节。它的概要是:

#include <jni.h>       /* where everything is defined */

int main() {
  JavaVM *jvm;       /* denotes a Java VM */
  JNIEnv *env;       /* pointer to native method interface */
  JDK1_1InitArgs vm_args; /* JDK 1.1 VM initialization arguments */
  vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
  /* Get the default initialization arguments and set the class 
   * path */
  JNI_GetDefaultJavaVMInitArgs(&vm_args);
  vm_args.classpath = ...;
  /* load and initialize a Java VM, return a JNI interface 
   * pointer in env */
  JNI_CreateJavaVM(&jvm, &env, &vm_args);
  /* invoke the Main.test method using the JNI */
  jclass cls = env->FindClass("Main");
  jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
  env->CallStaticVoidMethod(cls, mid, 100);
  /* We could have created an Object and called methods on it instead */
  /* We are done. */
  jvm->DestroyJavaVM();
}

如果需要,您可以执行更复杂的操作(例如,自定义类加载器),但这是根据在应用程序中运行JVM所需的最低限度来实现的。

答案 1 :(得分:3)

对于是否要将Java嵌入到C ++应用程序或其他方面,似乎存在一些混淆。我将采取每个案例。

  1. 要将java嵌入到c ++应用程序中,可以对java程序进行套接字调用。在java端,使用SocketServer,在C ++端,使用通用套接字层库。这是迄今为止最简单,最具扩展性的方法。随着您的java工作负载不断增加,您不断添加额外的jvm。部署稍微复杂但是,它的效果非常好。

  2. 用于在java中嵌入C ++应用程序。这很简单。您将C ++应用程序编译到共享库中并使用JNI来调用它。

答案 2 :(得分:2)

  

我基本上想要做的是将Java嵌入到这个应用程序中。   这已经用Python完成了(不是由我完成的)。

JNI Invocation API支持此功能,如@awoodland所述。 Here's a current link, for Java 6/7

  

我想做的是,使用Java中的C ++类进行交互   与申请。在这种情况下,它是一个3D应用程序,称为Cinema 4D。

为此,您可以使用以下方法之一:

  • 在C
  • 中实现的Java本机方法
  • JNA
  • SWIG
  

有没有办法在应用程序中编译和评估Java代码   正在运行(使用某种脚本语言)使用JNI或任何东西   喜欢吗?

您可能会对

BeanShellGroovy等感兴趣。两者都支持在JVM上运行的动态解释代码。

答案 3 :(得分:1)

我最近一直在做类似的事情。对我有用的是使用库jni.h,当你安装java(Java \ jdk [version] \ include)并在visual studio中用c / c ++代码创建一个dll时。例如:

Test.h

//declare the method you want to implement in c/c++ in the header
//include the jni header
#include <jni.h>
JNIEXPORT void JNICALL Java_Test_print(JNIEnv *, jobject);
//Java_[Class Name]_[Method Name](pointer to JVM, java object);

Test.cpp的

extern "C" JNIEXPORT void JNICALL Java_WinampController_printTrackInfo (JNIEnv *env, jobject obj){
    printf("Hey, I'm a java method in c (or not?)\n");
}

然后使用Visual Studio创建一个dll,并在 静态 块中加载dll。 我没有在没有编译dll中的c / c ++代码的情况下尝试,也许还有另一种方法来调用c / c ++代码。但这就是你实现它的方式。

Test.java

//declare the same method native inside a class in java
public class Test{
    static {
        System.loadLibrary("Test"); //load the dll
    }
    public native void print();
} //after that you just call test.print() normally

所以,你只需要用你想要的所有c / c ++实现java方法。

如果您仍然不知道该怎么做,请在这里启发自己:

Java Native Interface Specification - Oracle

Java Native Interface - Wikipedia

答案 4 :(得分:0)

对于您描述的场景,JNI可能是最好的方法。您将把C ++应用程序的功能公开为DLL,可以将其合并到Java应用程序中并从中使用。

答案 5 :(得分:-2)

您可能需要重新考虑您的设计。 Java不是这类任务的好选择。 java标准库中没有eval()函数,类似于python或shell中的eval()

您可以使用JNI在C ++代码中创建一个Java VM,但它有点沉重。仍然存在如何从java源创建字节码的问题。您将不得不嵌入大量代码来编译和运行C ++中的Java代码。不要那样做。必须有更好的解决方案。

例如,您可以在C ++代码和单独的Java代码之间使用一些RPC(SOAP,XML-RPC,Corba)。如果你需要做一些eval() - 比如java调用,你可以使用Groovy或Jython(都有eval(),访问所有标准的java库,并且可以运行常规的java类。)