2011-09-21 46 views
17

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

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

我读了一些关于JNI的内容,但总是有来自使用Java类的完整程序的讲话。

我想要做的是使用Java中的C++类来与应用程序交互。
这是一款名为Cinema 4D的3D应用程序。

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

例假想代码嵌入已完成后:

import c4d.documents.*; 

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

此代码应以影院4D交互以删除所选择的对象。

+0

你需要完整的Java SE或只是一些最起码的VM? –

+0

如果你已经确定这种语言必须是Java,你为什么要说“某种脚本语言”? – jalf

+0

@MichałŠrajer这实际上仍然是开放的,Java和应用程序之间的基本交互对于开始来说会很好。 –

回答

37

您可以在应用程序中嵌入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中工作你的申请。

+0

现在,这不是用于从C++调用Java方法吗?我实际上需要它:) –

+2

随着swig,你可以生成绑定,让你从java调用C++。这个问题意味着你需要这种方式。您也可以在一个程序中执行这两个操作。 – Flexo

+0

我的两分钱:因为OP想要加载插件,所以我认为他还应该阅读一下自定义类加载器如何让他阅读“插件jar”。此外,您需要具有本地方法(即JNI)的Java类从Java调用C++。 –

0

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

-1

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

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

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

2

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

JNI调用API支持这一点,如@awoodland所述。 Here's a current link, for Java 6/7

我想要做的是,使用Java中的C++类来与应用程序交互 。这是一款名为Cinema 4D的3D应用程序。

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

实现的方法有没有办法编译并在应用程序中评估Java代码正在运行(使用某种脚本语言)使用JNI或任何其他 喜欢它?

BeanShellGroovy等等,可能会引起您的兴趣。两者都支持在JVM上运行的动态解释代码。

+0

为了从Java调用C++,我建议也看看[BridJ](http://code.google.com/p/bridj)+ [JNAerator](http://code.google.com/p/jnaerator)。 – zOlive

3

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

  1. 要将java嵌入到C++应用程序中,可以调用java程序的套接字调用。在java端,使用SocketServer,在C++端使用通用套接字层库。这是迄今为止最简单和最可扩展的方法。随着您的Java工作负载不断增加,您不断添加额外的jvm。部署起来有点复杂,但它工作得很好。

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

1

最近我一直在做类似的工作。对我而言,使用安装java(Java \ jdk [version] \ include)时创建的库jni.h,并在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

相关问题