将 Java 嵌入到 C++ 应用程序中?
Posted
技术标签:
【中文标题】将 Java 嵌入到 C++ 应用程序中?【英文标题】:Embed Java into a C++ application? 【发布时间】:2011-09-21 20:39:33 【问题描述】:我有一个用 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 交互以删除所选对象。
【问题讨论】:
您需要完整的 java SE 还是只需要一些最小的 VM? 如果您已经确定这种语言必须是 Java,为什么还要说“某种脚本语言”? @MichałŠrajer 这实际上仍然是开放的,Java 和应用程序之间的基本交互对于开始来说会很棒。 @jalf: 应该不需要重新启动应用程序来运行新添加的 Java 代码,我想在 C4D 中编写一个可以直接运行代码的“IDE”跨度> @NiklasR - “基本交互”对于套接字来说听起来不错。 【参考方案1】:您可以在应用程序中嵌入 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 在你的应用程序中运行所需的最低限度。
【讨论】:
现在,这不是从 C++ 调用 Java 方法吗?我实际上需要它反过来:) 使用 swig,您可以生成绑定,让您可以从 java 调用 C++。这个问题暗示你想要这种方式。您也可以在一个程序中同时完成这两项工作。 我的两分钱:既然 OP 想要加载插件,我认为他还应该阅读自定义类加载器如何让他读取“插件 jar”。此外,您需要具有本地方法(即 JNI)的 Java 类才能从 Java 调用 C++。【参考方案2】:您是否希望将 Java 嵌入到 C++ 应用程序中或反之,似乎有些困惑。我会处理每个案例。
为了将 java 嵌入到 c++ 应用程序中,您可以对 java 程序进行套接字调用。在 java 端,您使用 SocketServer,在 C++ 端,您使用通用套接字层库。这是迄今为止最简单和最具可扩展性的方法。随着您的 java 工作负载不断增加,您不断添加额外的 jvm。部署有点复杂,但是效果很好。
用于在 java 中嵌入 C++ 应用程序。这很简单。您将 C++ 应用程序编译为共享库并使用 JNI 调用它。
【讨论】:
【参考方案3】:我基本上想做的是将Java嵌入到这个应用程序中。 这已经用 Python 完成了(不是我做的)。
如@awoodland 所述,JNI 调用 API 支持这一点。 Here's a current link, for Java 6/7.
我想做的是,在 Java 中使用 C++ 中的类进行交互 与应用程序。在这种情况下,它是一个 3D 应用程序,称为 Cinema 4D。
为此,您可以使用以下方法之一:
用 C 实现的 Java 本机方法 JNA SWIG有没有办法在应用程序的同时编译和评估 Java 代码 正在使用 JNI 或任何东西运行(以某种脚本语言) 喜欢吗?
BeanShell 或 Groovy 等可能会引起您的兴趣。两者都支持在 JVM 上运行的动态解释代码。
【讨论】:
要从 Java 调用 C++,我建议也看看 BridJ + JNAerator。【参考方案4】:我最近一直在做类似的事情。对我有用的是使用安装 java (Java\jdk[version]\include) 时附带的库 jni.h 并在 Visual Studio 中使用 c/c++ 代码创建 dll。例如:
测试.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 并在 static 块中加载该 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
【讨论】:
【参考方案5】:对于您描述的场景,JNI 可能是最好的方法。您会将 C++ 应用程序的功能公开为一个 DLL,该 DLL 可以合并到 Java 应用程序中并从中使用。
【讨论】:
【参考方案6】:您可能需要重新考虑您的设计。对于此类任务,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类)。
【讨论】:
以上是关于将 Java 嵌入到 C++ 应用程序中?的主要内容,如果未能解决你的问题,请参考以下文章
将 Python 嵌入到 C++ 应用程序中,无论是不是安装了 Python(在 Windows 上)
如何将多媒体 HTML/JavaScript 应用程序嵌入到 C++ 代码中