2011-12-27 6 views
3

私はC++で書かれたプログラムのためのプラグインを書いています。C++からclojureコードを呼び出すことはできますか?

プラグインは特定のディレクトリに配置され、メインアプリケーションから呼び出されます。私はClojure(GUI、計算など)にプラグインのほとんどを書いていますが、実際の「プラグイン」はC++で書かれている必要があります。さまざまなデータをC++からClojureに渡す必要があります。

どうすればいいですか?

JNI/JNA、ソケット、システムコール? (私が大したことは分かりません)

+0

はClojureのを使用しないでください。ウィキペディアの簡単なスキャンは、Java VMで実行されているように見えますが、CLRもサポートしており、JavaScriptまでコンパイルできます。いずれにしても、C++からネイティブではないので、何らかのラッパーDLL、Webサービス、またはその両方が必要になります。 – AJG85

+5

この質問には2つの部分があります:1)C++からJavaをどのように呼び出すか、そして2)JavaからClojureを呼び出す方法は2つあります。後者はあまり難しくありません。http://clojure.org/java_interopは出発点です。最初の質問は、要件と環境によって異なります。私が長年勤めていたプロジェクトでは、ソケットを使いました:http://sourceforge.net/projects/jradius/ – Gert

答えて

1

JNIはこれにはかなり簡単です。

私はこの方法でそれに近づくでしょう。明確に定義された外部インタフェース、メソッド/あなたが呼び出すために必要な機能の すなわち、どのようなセットでお使いのClojureコードを開発

  1. (よく としてのClojureのLIBSを含む)、スタンドアロンuberjarとしてパッケージにそれを
  2. は、次の操作を行う必要がありますあなたのC++ラッパー、書き込み:
    • を(これを参照してくださいクラスパス上のあなたのuberjarとJVMを作成しますリンク:http://java.sun.com/docs/books/jni/html/invoke.html
    • は、基礎となるJavaメソッドにC++の機能をマップするファサード(Clojureの関数)
0を提供し、あなたのClojureクラス
  • をロード

    メインクロージャークラスを作成し、適切なメソッドを呼び出す単純なスタンドアロンのJavaテストハーネスを使用して、ステップ2のuber-jarをテストできます。これにより、ステップ3のjni呼び出しで問題が発生した場合に備えて、適切なjava/clojure jarファイルがあることがわかります。

    jni参照を確認する際には、 cとC++のjniリンケージ。

    幸運。

  • 2

    私はこの質問が古いことを知っていますが、おそらく誰かがこれを便利に思っています。私はlispのか、マクロのファンではないよう

    #include <jni.h>  /* where everything is defined */ 
    #include <cstring> 
    
    int main() { 
        JavaVM *jvm;  /* denotes a Java VM */ 
        JNIEnv *env;  /* pointer to native method interface */ 
        JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */ 
        JavaVMOption* options = new JavaVMOption[1]; 
        options[0].optionString = "-Djava.class.path=/home/raoof/.m2/repository/org/clojure/spec.alpha/0.1.143/spec.alpha-0.1.143.jar:/home/raoof/.m2/repository/org/clojure/clojure/1.9.0/clojure-1.9.0.jar"; 
        vm_args.version = JNI_VERSION_1_6; 
        vm_args.nOptions = 1; 
        vm_args.options = options; 
        vm_args.ignoreUnrecognized = false; 
        /* load and initialize a Java VM, return a JNI interface 
        * pointer in env */ 
        JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); 
        delete options; 
    
        jclass Clojure = env->FindClass("clojure/java/api/Clojure"); 
        jmethodID var = env->GetStaticMethodID(Clojure, "var", "(Ljava/lang/Object;Ljava/lang/Object;)Lclojure/lang/IFn;"); 
        jobject load_string = env->CallStaticObjectMethod(Clojure, var, env->NewStringUTF("clojure.core"), env->NewStringUTF("load-string")); 
        jmethodID load_string_invoke = env->GetMethodID(env->GetObjectClass(load_string), "invoke", "(Ljava/lang/Object;)Ljava/lang/Object;"); 
        env->CallObjectMethod(load_string, load_string_invoke, env->NewStringUTF("(prn (+ 1 2 3 4 5))")); 
    
        jvm->DestroyJavaVM(); 
    } 
    

    、その後

    g++ -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux/ -L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server -ljvm clojurejvm.cpp 
    LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server ./a.out 
    
    関連する問題