Clojure的用户通常希望尽可能地懒惰,并延迟类和对象的创建。本着同样的精神,如果我希望调用运行时在Java中解析的 native 函数,则可以使用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来执行类似于运行时绑定(bind)JNA示例的操作。有人可以演示如何吗?此外,如果可能的话,这种方法是否会对性能造成任何不利影响?否则,似乎提前生成Java源文件是唯一的解决方案。如果有人可以确认这一点,我将不胜感激。

最佳答案

编辑:

在更好地理解了问题并专注于“动态”(没有进行预编译)之后,我仍然犹豫声称“这是不可能的”(“不可能”是一个非常强烈的词/意思,就像“总是”/“永远不会”),但我非常确定这不是BridJ的标准例程。
我可以想到使用Bridj的动态解决方案,但这很可能取决于“JNAerator”,而这又取决于“JNA”(您的起始位置)。

原始答案描述了“使用BridJ动态调用任何 native 函数”(涉及代码生成)的“标准例程”:

根据https://code.google.com/p/bridj/https://code.google.com/p/bridj/wiki/FAQ,您必须:

  • 设置一个bridJ项目(java项目+ bridJ依赖项)
  • 对您的库运行the JNAerator(带有bridJ输出选项)。这将生成Java文件,用作导出功能的“ stub /代理”。
  • 您的Java代码可以引用/使用这些“ stub ”,并且(应该)调用您的库。

  • 从“他们的快速入门”中获取的样本:


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



    (这是生成的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);
      }
    }
    

    希望这可以帮助!

    10-08 03:34