web-dev-qa-db-ja.com

JavaをC ++アプリケーションに埋め込みますか?

C++で記述されたアプリケーションを入手し、C++でプラグインを記述してアプリケーションの機能を拡張することができます。

私が基本的にやりたいことは、Javaをこのアプリケーションに埋め込むことです。これは、Pythonですでに行われています)(私は行いません)。

私はJNIについて何か読みましたが、Javaクラスを使用する完全なプログラムからのスピーチは常にあります。

私がやりたいのは、C++のクラスをJavaで使用してアプリケーションと対話することです。
これは、この場合は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();
    }
  }
}

このコードは、Cinema 4Dと対話して、選択したオブジェクトを削除する必要があります。

22
Niklas R

アプリケーション内にJVMを組み込むことができます。 Oracleの 公式リファレンスブック には、もう少し詳細があります。その概要は次のとおりです。

#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を動作させるために必要な最低限のことです。

44
Flexo

JavaをC++アプリに埋め込むのか、それともその逆にするのかについて、いくつかの混乱があるようです。それぞれのケースを取り上げます。

  1. Javaをc ++アプリに埋め込む場合は、Javaプログラムにソケット呼び出しを行うことができます。Java終了時に、 SocketServerを使用し、C++側ではGeneral Socket Layerライブラリを使用します。これは、最も簡単でスケーラブルなアプローチです。Javaワークロードが増え続けるにつれて、jvmを追加し続けます。少しデプロイは複雑ですが、非常にうまく機能します。

  2. JavaにC++アプリを埋め込むため。これは簡単です。 C++アプリを共有ライブラリにコンパイルし、JNIを使​​用してそれを呼び出します。

3
RHT

私が基本的にやりたいことは、Javaをこのアプリケーションに埋め込むことです。これはすでにPython(私が行っていない)で行われています)。

JNI呼び出しAPIは、@ awoodlandで説明されているように、これをサポートしています。 Java 6/7 の現在のリンクです。

私がやりたいのは、C++のクラスをJavaで使用してアプリケーションとやり取りすることです。この場合、3Dアプリで、Cinema 4Dと呼ばれます。

これには、次のいずれかを使用できます。

アプリケーションの実行中に(ある種のスクリプト言語で)JNIまたはそれに類するものを使用してJavaコードをコンパイルおよび評価する方法はありますか?

BeanShell または Groovy は、特に興味深いかもしれません。どちらも、JVMで実行される動的に解釈されるコードをサポートしています。

2
Andy Thomas

最近、似たようなことをしている。私にとってうまくいったのは、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をstaticブロック内にロードします。 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

1
0rkan

あなたがJNIを説明しているシナリオでは、おそらく最善の方法です。 C++アプリの機能をDLLとして公開します。これは、Javaアプリケーションに組み込んで使用することができます。

0
Perception