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

发布于 2024-12-05 16:52:51 字数 586 浏览 0 评论 0原文

我有一个用 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 交互以删除所选对象。

I got an application written in C++ and I am able to extend the applications functionality by writing plugins in C++ for it.

What I basically want to do is to embed Java into this application. This has already been done with Python (not done by me).

I read something about JNI but there is always the speech from a full programm that uses Java classes.

What I'd like to do is, to use classes from C++ in Java to interact with the application.
It's a 3D app in this case, called Cinema 4D.

Is there a way to compile and evaluate Java code while the application is running (in some sort of scripting language) using JNI or anything like it ?

Example imaginary code after the embedding was done:

import c4d.documents.*;

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

This code should interact with Cinema 4D to delete the selected object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清音悠歌 2024-12-12 16:52:51

您可以在应用程序中嵌入 JVM。 Oracle 的官方参考书提供了更多详细信息。其概要如下:

#include ; /* 一切都被定义的地方 */

int main() {
  JavaVM *jvm; /* 表示 Java 虚拟机 */
  JNIEnv *env; /* 指向本机方法接口的指针 */
  JDK1_1InitArgs vm_args; /* JDK 1.1 VM 初始化参数 */
  vm_args.version = 0x00010001; /* 1.1.2 中的新增功能:VM 版本 */
  /* 获取默认初始化参数并设置类 
   * 小路 */
  JNI_GetDefaultJavaVMInitArgs(&vm_args);
  vm_args.classpath = ...;
  /* 加载并初始化一个Java VM,返回一个JNI接口 
   * 环境中的指针 */
  JNI_CreateJavaVM(&jvm, &env, &vm_args);
  /* 使用 JNI 调用 Main.test 方法 */
  jclass cls = env->FindClass("Main");
  jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
  env->CallStaticVoidMethod(cls, mid, 100);
  /* 我们可以创建一个对象并调用它的方法 */
  /* 我们完成了。 */
  jvm->DestroyJavaVM();
}

如果您愿意,您可以做更复杂的事情(例如自定义类加载器),但这只是让 JVM 在您的应用程序中工作所需的最低限度。

You can embed a JVM within your application. Oracle's official reference book has some more details. The synopsis of it is:

#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();
}

You can do far more sophisticated things if you want (e.g. custom class loaders) but that's about it in terms of the bare minimum needed to get a JVM working within your application.

倾城花音 2024-12-12 16:52:51

对于是否要将 Java 嵌入到 C++ 应用程序中或反之亦然,似乎存在一些困惑。我会处理每个案例。

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

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

There seems to be some confusion over whether you want to embed Java into the C++ app or the other way around. I will take each case.

  1. For embedding java into c++ app, you can make a socket call to the java program. On java end, you use SocketServer and on the C++ end, you use the General Socket Layer library. This is by far the easiest and most scalable approach. As your java workload keeps increasing, you keep adding additional jvm. Slightly complicated to deploy but, it works really well.

  2. For embedding C++ app in java. This is simple. You compile C++ app into a shared library and use JNI to invoke it.

南…巷孤猫 2024-12-12 16:52:51

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

JNI 调用 API 支持这一点,如 @awoodland 所描述。 这是 Java 6/ 的当前链接7.

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

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

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

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

BeanShell您可能会对 Groovy 等感兴趣。两者都支持在 JVM 上运行的动态解释代码。

What I basically want to do is to embed Java into this application.
This has already been done with Python (not done by me).

The JNI Invocation API supports this, as described by @awoodland. Here's a current link, for Java 6/7.

What I'd like to do is, to use classes from C++ in Java to interact
with the application. It's a 3D app in this case, called Cinema 4D.

For this you could use one of the following:

  • Java native methods implemented in C
  • JNA
  • SWIG

Is there a way to compile and evaluate Java code while the application
is running (in some sort of scripting language) using JNI or anything
like it ?

BeanShell or Groovy, among others, might be of interest to you. Both support dynamically interpreted code that runs on the JVM.

雄赳赳气昂昂 2024-12-12 16:52:51

我最近一直在从事类似的工作。对我有用的是使用安装 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,并在 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 本机接口规范 - Oracle

Java 本机接口 - 维基百科

I've been working in something similar lately. What worked for me was using the library jni.h that comes when you install java (Java\jdk[version]\include) and creating a dll with c/c++ code in visual studio. For example:

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");
}

Then create a dll with Visual Studio and load the dll within a static block.
I didn't try that without compiling the c/c++ code in a dll, maybe there's another way to call the c/c++ code. But that's how you implement it.

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

So, you just do that and implement java methods with all c/c++ you want.

If you still don't know how to do it, enlighten yourself here:

Java Native Interface Specification - Oracle

Java Native Interface - Wikipedia

大姐,你呐 2024-12-12 16:52:51

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

For the scenario you are describing JNI is probably the best way to go. You would be exposing the functionality of your C++ app as a DLL that can be incorporated into and used from a Java application.

幼儿园老大 2024-12-12 16:52:51

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

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

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

You probably need to rethink your design. Java is not a good choice for this kind of tasks. There is no eval() function in java standard library similar to eval() from python or shell.

You can create a java VM in C++ code using JNI but it's kind of heavy. There is still issue how to create a bytecode from a java source. You will have to embed a lot of code to compile and run java code in C++. Don't do that. There must be better solution.

You can for example use some RPC (SOAP, XML-RPC, Corba) between your C++ code and separate java code. If you need to do some eval()-like java invocation, you can use Groovy or Jython (both has eval(), access to all standard java library and can run regular java classes).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文