Clojure的用户通常希望尽可能地懒惰,并延迟创建类和对象。本着同样的精神,如果我想调用在Java中运行时解析的本机函数,我可以使用com.sun.jna.Function.getFunction("foolibrary", "foofuncname")
,它返回com.sun.jna.Function
,可以是invoked
。< / p>
在Clojure中,这看起来像:
(let [f (com.sun.jna.Function/getFunction "c" "printf")]
(.invoke f Integer (to-array ["Hello World"])))
另一方面,BridJ提供了一个有吸引力的性能优势并声称更简单的API,但是,我仍然不清楚如何使用BridJ来执行类似于运行时绑定JNA示例的操作。有人可以演示如何?此外,如果可以,这种方法是否有任何性能损失?否则,似乎提前生成Java源文件是唯一的解决方案。如果有人能证实这一点,我将不胜感激。
答案 0 :(得分:2)
编辑:
更好地理解问题&amp;专注于“动态”(没有预先编译),我仍然犹豫要声称“这是不可能的”(“不可能”是一个非常强大的词/意思......就像“永远”/“从不“),但我非常确定这不是BridJ的标准程序。 我可以想到Bridj的动态解决方案,但这很可能取决于“JNAerator”,而这又取决于“JNA”(你的起始位置)。
原始答案,描述“使用BridJ动态调用任何本机函数”的“标准例程”(包括代码生成):
根据https://code.google.com/p/bridj/和https://code.google.com/p/bridj/wiki/FAQ,您必须:
取自“他们的快速启动”的样本:
原始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);
}
}
希望这有帮助!