标签:invoke 开发 示例 space get object section eal ted
本文是对 JNI 技术的一个补充方法,提出了替换 JNI、JNA 的一种开源技术。首先对 JavaCPP 技术进行简单介绍及对应于其他现有方案的介绍、对比。接下来,通过一个简单的示例让大家了解 JavaCPP 的工作原理。然后,介绍了 JavaCPP presets 子项目,最后通过若干个针对 presets 的示例来让大家了解如何使用它,本文主要提出了替换 JNI 的一种编程实现方式。
JavaCPP 是一个开源库,它提供了在 Java 中高效访问本地 C++的方法。采用 JNI 技术实现,所以支持所有 Java 实现包括 Android 系统,Avian 和 RoboVM。
一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。
Avian 是一个轻量级的 Java 虚拟机和类库,提供了 Java 特性的一个有用的子集,适合开发跨平台、自包容的应用程序。它实现非常快速而且体积小,主要特性包括如下四点:
RoboVM 编译器可以将 Java 字节码翻译成 ARM 或者 x86 平台上的原生代码,应用可直接在 CPU 上运行,无需其他解释器或者虚拟机。RoboVM 同时包含一个 Java 到 Objective-C 的桥,可像其他 Java 对象一样来使用 Objective-C 对象。大多数 UIKit 已经支持,而且将会支持更多的框架。
总的来说,JavaCPP 提供了一系列的 Annotation 将 Java 代码映射到 C++代码,并使用一个可执行的 jar 包将 C++代码转化为可以从 JVM 内调用的动态链接库文件。
与其他技术相比,特性总结如下表 1 所示。
技术名称 | 技术介绍 |
---|---|
CableSwig | 用于针对 Tcl 和 Python 语言创建接口 |
JNIGeneratorApp | 所有用于 SWT 的 C 代码都是通过它来创建的 |
cxxwrap | 用于生成针对 C++的 Java JNI 包、HTML 文档、用户手册 |
JNIWrapper | 商业版本,可以帮助实现 Java 和本地代码之间的无缝结合 |
Platform Invoke | 微软发布的一个工具 |
GlueGen | 针对 C 语言的一个工具,帮助生成 JNI 代码 |
LWJGL Generator | JNI 代码生成器 |
ctypes | 针对 Python 的接口代码生成器 |
JNA | JNA(Java Native Access)提供一组 Java 工具类用于在运行期动态访问系统本地库(native library:如 Window 的 dll)而不需要编写任何 Native/JNI 代码。开发人员只要在一个 Java 接口中描述目标 native library 的函数与结构,JNA 将自动实现 Java 接口到 native function 的映射。 |
JNIEasy | 替换 JNA 的一种技术 |
JNative | Windows 版本的库 (DLL),提供了 JNI 代码生成 |
fficxx | 针对 haskell 模型的代码生成器,主要生成 C 语言 |
JavaCPP | 更加自然高效,它支持大部分的 C++语法特性。目前已经能成功封装 OpenCV, FFmpeg, libdc1394, PGR FlyCapture, OpenKinect, videoInput, and ARToolKitPlus。除此之外,它还能直接把 C/C++的头文件转化成 Java 类,能自动生成 JNI 代码,编译成本地库,开发人员无需编写繁琐的 C++、JNI 代码,从而提高开发效率。 |
为了调用本地方法,JavaCPP 生成了对应的 JNI 代码,并且把这些代码输入到 C++编译器,用来构建本地库。使用了 Annotations 特性的 Java 代码在运行时会自动调用 Loader.load() 方法从 Java 资源里载入本地库,这里指的资源是工程构建过程中配置好的。
我们先来演示一个例子,这是一个简单的注入/读出方法,类似于 JavaBean 的工作方式。清单 1 所示的 LegacyLibrary.h 包含了 C++类。
#include <string> namespace LegacyLibrary { class LegacyClass { public: const std::string& get_property() { return property; } void set_property(const std::string& property) { this->property = property; } std::string property; }; }
接下来定义一个 Java 类,驱动 JavaCPP 来完成调用 C++代码。
import org.bytedeco.javacpp.*; import org.bytedeco.javacpp.annotation.*; @Platform(include="LegacyLibrary.h") @Namespace("LegacyLibrary") public class LegacyLibrary { public static class LegacyClass extends Pointer { static { Loader.load(); } public LegacyClass() { allocate(); } private native void allocate(); // to call the getter and setter functions public native @StdString String get_property(); public native void set_property(String property); // to access the member variable directly public native @StdString String property(); public native void property(String property); } public static void main(String[] args) { // Pointer objects allocated in Java get deallocated once they become unreachable, // but C++ destructors can still be called in a timely fashion with Pointer.deallocate() LegacyClass l = new LegacyClass(); l.set_property("Hello World!"); System.out.println(l.property()); } }
以上两个类放在一个目录下面,接下来运行一系列编译指令,如清单 3 所示。
$ javac -cp javacpp.jar LegacyLibrary.java $ java -jar javacpp.jar LegacyLibrary $ java -cp javacpp.jar LegacyLibrary Hello World!
我们看到清单 3 最后运行输出了一行“Hello World!”,这是 LegacyLibrary 类里面定义好的,通过一个 setter 方法注入字符串,getter 方法读出字符串。
我们可以看到文件夹里面内容的变化,刚开始的时候只有.h、.java 两个文件,清单 3 所示的 3 个命令运行过后,生成了 class 文件及本地方法 (native method) 对应的.so 文件。
http://www.ibm.com/developerworks/cn/java/j-lo-cpp/
标签:invoke 开发 示例 space get object section eal ted
原文地址:http://www.cnblogs.com/softidea/p/6102754.html