在 Java 中并使用 Bridj,您如何动态调用任何本机函数?
In Java and using Bridj, how can you dynamically invoke any native function?
Clojure 的用户通常希望尽可能地懒惰,并延迟 类 和对象的创建。本着同样的精神,如果我想调用一个在运行时从 Java 中解析的本机函数,我可以使用 com.sun.jna.Function.getFunction("foolibrary", "foofuncname")
,其中 returns 和 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 源文件是唯一的解决方案。如果有人能证实这一点,我将不胜感激。
编辑:
在更好地理解了问题并专注于“动态”(没有预编译)之后,我仍然犹豫是否声称 "it is impossible"("impossible" 是一个非常强大的word/meaning ...像"always"/"never"),但我非常确定这不是BridJ的标准例程。
我可以想到 Bridj 的动态解决方案,但这很可能取决于 "JNAerator",而这又取决于 "JNA"(您的起始位置)。
原答案,描述"standard routine" for "dynamically invoke any native function with BridJ"(涉及代码生成):
根据 https://code.google.com/p/bridj/ and https://code.google.com/p/bridj/wiki/FAQ,您必须:
- 设置 bridJ 项目(java 项目 + bridJ 依赖项)
- 运行 the JNAerator(使用 bridJ 输出选项)针对您的库。这将生成 Java 文件,作为导出函数的 "stubs/delegates"。
- 这些 "stubs" 可以通过您的 java 代码 referenced/used,并且(应该)调用您的库。
样本取自"their Quickstart":
Original C++ code :
/// 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);
}
Translation + binding with 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);
}
}
希望对您有所帮助!
Clojure 的用户通常希望尽可能地懒惰,并延迟 类 和对象的创建。本着同样的精神,如果我想调用一个在运行时从 Java 中解析的本机函数,我可以使用 com.sun.jna.Function.getFunction("foolibrary", "foofuncname")
,其中 returns 和 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 源文件是唯一的解决方案。如果有人能证实这一点,我将不胜感激。
编辑:
在更好地理解了问题并专注于“动态”(没有预编译)之后,我仍然犹豫是否声称 "it is impossible"("impossible" 是一个非常强大的word/meaning ...像"always"/"never"),但我非常确定这不是BridJ的标准例程。 我可以想到 Bridj 的动态解决方案,但这很可能取决于 "JNAerator",而这又取决于 "JNA"(您的起始位置)。
原答案,描述"standard routine" for "dynamically invoke any native function with BridJ"(涉及代码生成):
根据 https://code.google.com/p/bridj/ and https://code.google.com/p/bridj/wiki/FAQ,您必须:
- 设置 bridJ 项目(java 项目 + bridJ 依赖项)
- 运行 the JNAerator(使用 bridJ 输出选项)针对您的库。这将生成 Java 文件,作为导出函数的 "stubs/delegates"。
- 这些 "stubs" 可以通过您的 java 代码 referenced/used,并且(应该)调用您的库。
样本取自"their Quickstart":
Original C++ code :
/// 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);
}
Translation + binding with 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);
}
}
希望对您有所帮助!