6

多くの場合、Clojure のユーザーはできるだけ怠惰になり、クラスやオブジェクトの作成を遅らせたいと考えています。同じ精神で、実行時に Java 内から解決されるネイティブ関数を呼び出したい場合は、 を使用com.sun.jna.Function.getFunction("foolibrary", "foofuncname")できcom.sun.jna.Functionますinvoked

Clojure では次のようになります。

(let [f (com.sun.jna.Function/getFunction "c" "printf")]
  (.invoke f Integer (to-array ["Hello World"])))

一方、BridJ は魅力的なパフォーマンス上の利点を提供し、より単純な API を主張していますが、BridJ を使用してランタイム バインディング JNA の例と同様のことを行う方法はまだ明確ではありません。誰かが方法を示すことができますか? また、これが可能である場合、このアプローチでパフォーマンスが低下することはありますか? それ以外の場合は、事前に Java ソース ファイルを生成することが唯一の解決策のようです。誰かがこれを確認できれば幸いです。

4

1 に答える 1

4

編集:

質問をよりよく理解し、「動的」(事前コンパイルなし)に焦点を当てた後でも、「不可能」と主張することをためらっています(「不可能」は非常に強い言葉/意味です...「常に」/「決して」のように) ) ですが、これがBridJの標準ルーチンではないことは確かです。Bridj を使用した動的ソリューションを考えることができますが、これはおそらく「JNAerator」に依存し、これは「JNA」(開始位置) に依存する可能性が非常に高くなります。

「BridJを使用してネイティブ関数を動的に呼び出す」ための「標準ルーチン」を説明する元の回答(コード生成を含む):

https://code.google.com/p/bridj/およびhttps://code.google.com/p/bridj/wiki/FAQによると、次のことを行う必要があります。

  1. bridJ プロジェクトをセットアップする (Java プロジェクト + bridJ の依存関係)
  2. ライブラリに対してJNAeratorを (bridJ 出力オプションを使用して)実行します。これにより、エクスポートされた関数の「スタブ/デリゲート」として機能する Java ファイルが生成されます。
  3. これらの「スタブ」は、Java コードで参照/使用でき、ライブラリを呼び出す (必要な) ものです。

「彼らのクイックスタート」からのサンプル:

元の C++ コード:

/// exported in test.dll / libtest.so / libtest.dylib
class MyClass {
   public:
      MyClass();
      ~MyClass();
      virtual void virtualMethod(int i, float f);
      void normalMethod(int i);
};
void getSomeCount(int* countOut);
...
void test() {
  int count;
  getSomeCount(&count);
  MyClass t;
  t.virtualMethod(count, 0.5f);
}

翻訳 + BridJ とのバインディング:

(これは生成された Java コードです)

import org.bridj.*;     // C interop and core classes
import org.bridj.ann.*; // annotations
import org.bridj.cpp.*; // C++ runtime
import static org.bridj.Pointer.*; // pointer factories such as allocateInt(), pointerTo(java.nio.Buffer), etc...

@Library("test")
public class TestLibrary {
   static {
      BridJ.register(); // binds all native methods in this class and its subclasses
   }
   public static class MyClass extends CPPObject {
      @Virtual(0) // says virtualMethod is the first virtual method
      public native void virtualMethod(int i);
      public native void normalMethod(int i);
   };
   public static native void getSomeCount(Pointer<Integer> countOut);

   public static void test() {
      Pointer<Integer> pCount = allocateInt();
      getSomeCount(pCount);
      MyClass t = new MyClass();
      t.virtualMethod(pCount.get(), 0.5f);
  }
}

お役に立てれば!

于 2015-04-06T20:43:23.697 に答える