最近要使用JNI来做一些程序,花了一下午的时间,终于搞定,记录一下步骤,方便以后使用。
安装gcc等编译工具,我用的cygwin。。。真的很麻烦,不过终于搞定了。这个网上资料很多。
写natvie类,这个也没什么。
生成头文件,javah,也很简单,注意要用全路径,也就是包路径+类名,如java.lang.String
导入头文件和java的include里的所有文件也没问题。
编写c文件。
正戏来了,在编译成dll文件的时候,出现了十分令人郁闷的问题,java.lang.UnsatisfiedLinkError;hellonative.Main.nativePrint()V。这个说明dll文件找到了,但是方法找不到,经过查找,原来是编译的时候参数没有设置清楚,正确的应该是
-mno-cygwin -Wl,--kill-at -shared -m32
其中-mno-cygwin是说脱离cygwin环境,-m32是编译成32位,这两个一般情况下是可选的。--kill-at是关键,这个是说生成的文件中不要有@,必须要有该参数,否这就抛上面的异常。
另如果想把dll文件打包进jar中,可以用到下面的代码来做:
static {
try {
InputStream inputStream = Main.class.getResourceAsStream("HelloNative.dll");
// System.out.println(inputStream);
File temporaryDll = File.createTempFile("HelloNative", ".dll");
// System.out.println(temporaryDll.getAbsolutePath());
FileOutputStream outputStream = new FileOutputStream(temporaryDll);
byte[] array = new byte[8192];
int i = -1;
while ((i = inputStream.read(array)) != -1) {
outputStream.write(array, 0, i);
}
outputStream.close();
temporaryDll.deleteOnExit();
System.out.println(temporaryDll.getAbsolutePath());
System.load(temporaryDll.getPath());
} catch (Exception e) {
e.printStackTrace();
}
}
把文件复制进临时文件夹调用,因为system.load不能访问jar文件。
分享到:
相关推荐
值得注意的是,本书还特别提到了对JNI设计有重大贡献的个人和团队,例如Microsoft的Russ Arun、Apple的Patrick Beard、IBM的Simon Nash、Intel的Ken Root、还有参与设计讨论的Sun内部专家如Dave Bowen、James ...
Android NDK(Native Developer Kit)是Google为Android平台提供的一个开发工具,主要目的是...然而,值得注意的是,NDK开发也增加了代码复杂性,且不支持所有的Android Framework API,因此需要权衡利弊,适时使用。
2. **创建项目结构**:创建一个包含jni目录的Android项目,jni目录下是存放C/C++源码的地方。 3. **编写本地代码**:在jni目录下创建源码文件,如`hello-jni.c`,实现需要的功能。 4. **构建本地库**:使用`ndk-...
但是,对于性能敏感的应用,可能需要考虑使用JNI,因为JNI的调用速度通常比JNA更快,但编写和维护成本更高。 总之,"基于Java的调用本地库 JNAerator.zip"是一个实用的工具包,它帮助Java开发者轻松地集成本地库,...
值得注意的是,不同的第三方库可能会有不同的集成细节,因此在实际操作过程中还需根据具体库的文档进行调整。此外,随着Cocos2dx版本的更新,部分配置可能会发生变化,建议定期查看官方文档以获取最新指导。
值得注意的是,预览(preview)数据并不会直接从服务端复制到客户端,而是通过回调函数和内存映射机制将预览数据缓冲区的地址传递给客户端。这样设计的主要目的是为了提高性能,避免不必要的数据复制,减少内存消耗...
值得注意的是,使用C/C++实现可以显著减少性能开销,特别是在处理大量图像数据时。同时,由于操作在原生层,也可以更好地利用硬件加速,提高应用的响应速度和用户体验。在实际开发中,还需要考虑线程安全、内存管理...
值得注意的是,`-g0`显著减少了链接时间和dbx启动时间。 - **调试目标**:dbx支持多种调试目标类型,包括core file、ELF文件、Java class文件、Jar文件等。此外,还可以对运行中的进程进行调试。 - **环境准备**:...
对于每个段落,我们可以通过`Range`对象来获取其文本,但值得注意的是,`Range`不仅可以获取文本,还能包含表格和图片。在描述中,开发者选择仅处理文本,但实际情况下,`Range`可以进一步用于处理表格和图片,例如...
其中,以下几个关键的更新值得注意: 1. **Pattern Matching for instanceof(模式匹配用于instanceof)**:这是一个新的语法特性,允许开发者更简洁地检查对象是否符合特定类或接口。例如,`if (obj instanceof ...
值得注意的是,预构建时静态库和动态库不能同时存在,必须选择其中之一。 总结一下,Android NDK生成及连接静态库与动态库的关键步骤包括: 1. 创建jni目录并编写Android.mk和Application.mk文件。 2. 在Android.mk...
然而,值得注意的是,使用这类黑客工具不仅违反了游戏的用户协议,还可能导致账户被封禁。同时,开发和使用这类工具也可能触及法律问题,如侵犯版权和数字千年版权法等。因此,尽管这类技术的探索对于编程学习者来说...
值得注意的是,程序计数器是JVM规范中唯一一个不会出现内存溢出的区域。 虚拟机栈是每个线程在运行时所需的内存空间,它由多个栈帧组成。每个栈帧对应一个Java方法的调用,包括参数、局部变量和返回地址等。当一个...
值得注意的是,方法区也是垃圾回收的一部分,可以回收不再使用的类信息。 堆内存是所有线程共享的区域,用于存储Java程序创建的所有对象和数组。由于多线程共享,因此需要考虑同步问题。垃圾收集器会在堆中进行对象...