monodroid 调用 JNI Native 的一些问题

     在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对象。
      

转载于:https://www.cnblogs.com/kodong/p/4389622.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio中调用JNIJava Native Interface)可以实现Java与C/C++之间的相互调用。下面是一般的步骤: 1. 创建JNI文件夹:在Android Studio的项目目录下,创建一个名为"jni"的文件夹。 2. 创建C/C++源文件:在"jni"文件夹中创建一个C/C++源文件,例如"native-lib.c"。 3. 编写C/C++代码:在源文件中编写C/C++代码,实现所需的功能。 4. 生成头文件:在终端或命令提示符中,进入到"jni"文件夹,并执行以下命令生成头文件: ``` javah -d ../app/src/main/cpp -classpath ../app/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes com.example.appname.MainActivity ``` 这里的"com.example.appname.MainActivity"是你的Java类的完整路径。 5. 配置CMakeLists.txt:在项目的根目录下找到"CMakeLists.txt"文件,并添加以下内容: ``` # 设置C/C++源文件路径 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -std=c++11") add_library(native-lib SHARED src/main/cpp/native-lib.c) # 链接JNI库 target_link_libraries(native-lib log) ``` 6. 在Java代码中加载JNI库:在需要使用JNIJava类中,使用`System.loadLibrary("native-lib")`加载JNI库。 7. 调用JNI方法:在Java代码中,使用`native`关键字声明需要调用JNI方法,并在C/C++代码中实现对应的JNI方法。 8. 构建和运行:点击Android Studio的"Build"菜单,选择"Make Project"来构建项目。然后可以在Java代码中调用JNI方法。 希望以上步骤对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值