monodroid 调用 JNI Native 的一些问题
2024-08-26 11:11:43
在Android版本开发的过程中,需要使用一些用JNI开发的NDK的native库。这里谈一谈踩到的坑,给大家参考。
虽然java的程序我还算熟悉,但是没有了解过 JNI Native 的开发,一般是直接开发的.Net调用.so库。有一个库是从 Java 代码移植,且没有源码,于是乎碰到了一些问题。
一、JNI 对函数的命名是有要求的,.Net则可以直接调用原生看的函数库
例如monodroid 例子
[DllImport ("sanangeles", EntryPoint = "Java_com_example_SanAngeles_DemoRenderer_nativeInit")]
private static extern void nativeInit (IntPtr jnienv);
java 要求按照 Java_pakcage_class_method进行命名。
看看Java的声明
class DemoRenderer implements GLSurfaceView.Renderer {
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
nativeInit();
}
private static native void nativeInit();
}
如果你没有 JNI 的源码,不知道函数声明,你这样写
[DllImport ("sanangeles", EntryPoint = "nativeInit")]
private static extern void nativeInit (IntPtr jnienv);
那就等玩玩吧,如果你改进Java的源码,一定注意EntryPoint的声明。
二、找不到库,指令集的(eabi,eabi-v7a)的问题
默认调试的情况下,xamarin 调试状态,会根据android环境,选择执行的指令集。问题来了,它不能让你选择。于是乎你的libs只有eabi的.so,就会出现dll无法找到的问题。
调试状态,把eabi-v7a的目标库也添加进来。或者使用虚拟机的时候,选择armeabi 的环境。
你可以通过adb shell,到系统中查看库有没有被复制到 /data/app/package/lib 目录。
三、JNI 返回String的处理。
monodroid 介绍的很多方法,是通过 JNIEnv 类反射调用,没有必要非要使用反射方式
var ver = xxx(JNIEnv.Handle);
var s = new Java.Lang.Object(ver, JniHandleOwnership.TransferGlobalRef).JavaCast<Java.Lang.String>().ToString();
ver 是 IntPtr,这样避免使用反射,多进行几次转换。
建议:
如果使用NDK编写的函数库只是用monodroid来调用,没有必要使用JNI的规范,这样效率会更高,也无需传入JNIEnv对象。
最新文章
- html5 canvas常用api总结(二)--绘图API
- TCP状态
- 使用Intellij IDEA搭建Ext JsMVC web项目
- .NET LINQ 转换数据类型
- javascript数组浅谈1
- 关于2440的裸跑程序中SD卡读后不能成功写入问题的讨论
- 尝鲜basic开发android
- JS列
- RMAN duplicate from active 时遭遇 ORA-17627 ORA-12154
- 每天一个Linux命令(02)--cd命令
- WebGIS开源解决方案之开发环境搭建(一)
- 【轉】使用jQuery播放/暂停 HTML5视频
- zepto的返回顶部scrollTop的动画解决方法
- 移动web页面给用户发送邮件的方法
- Linux内核之内存管理
- blfs(systemv版本)学习笔记-为桌面环境构建xorg服务
- Android--解决EditText放到popupWindow中,原有复制、粘贴、全选、选择功能失效问题
- mongo 操作小结
- Linq-语句之存储过程
- Sublime Text 编辑器的设定