`
star65225692
  • 浏览: 277155 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类

JNI的输入和输出示例

JNI 
阅读更多

     本文通过两个例子来讲解JNI的一个输入/输出应用。首先看一个String的输入输出的例子,下面是java部分的代码

public class Prompt {

private native String getLine(String prompt);

public static void main(String args[]) {
     Prompt p = new Prompt();
     String input = p.getLine("Type a line: ");
     System.out.println("User typed: " + input);
}

static {
   System.loadLibrary("Prompt");
  }
}

        native方法是调用c/c++等语言接口的方法,Static静态代码块加载dll文件,本例中dll文件的名称是Prompt.dll。
编译这个java类,得到class文件,用javah命令生成头文件(javah -jni Prompt),运行成功将获得一个Prompt.h文件,打开该文件可看到以下代码风之境地

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Prompt */

#ifndef _Included_Prompt
#define _Included_Prompt
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     Prompt
* Method:    getLine
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_Prompt_getLine
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif


以下是一个C语言编写的小代码
   
    #include <jni.h>
    #include <stdio.h>
    #include "Prompt.h"
   
    JNIEXPORT jstring JNICALL
    Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
    {
        char buf[128];
        const char *str;
        str = (*env)->GetStringUTFChars(env, prompt, NULL);
        if (str == NULL) {
            return NULL;
        }
        printf("%s", str);
        (*env)->ReleaseStringUTFChars(env, prompt, str);
        scanf("%s", buf);
        return (*env)->NewStringUTF(env, buf);
}

用vc里的cl可生成dll文件。

本程序运行过程:
  运行java程序,main方法内有三句:
      
       Prompt p = new Prompt();
       建立本类实例,这将执行静态块加载dll文件。
      
       String input = p.getLine("Type a line: ");
       执行本地方法,我认为这将到头文件Prompt.h中去找执行的方法,于是就找到了这句
       JNIEXPORT jstring JNICALL Java_Prompt_getLine(JNIEnv *, jobject, jstring);
  进而执行c语言中的方法
       执行本方法最困惑的是“如何将java中本地方法的那个String类型的参数转化成C语言中要接收的参数,C语言返回的参数又要转化为java的String”。
       在 jni.h(应该是在jdk中include文件架下的一个头文件)中定义了基本类型的转换(int - jint , float - jfloat 等),本地代码会调用jni的函数获取相应的内容,例如本例中的GetStringUTFChars函数,该函数将JString转化为了C语言中的 String,然后可以作为标准的C语言变量使用,处理后返回一个jString变量。
      
       System.out.println("User typed: " + input);
       打印结果。
      
       下面看另外一个例子。
       java代码:

       public class InstanceFieldAccess {
      
       private String s;
      
       private native void accessField();
      
       public static void main(String args[]) {
               InstanceFieldAccess c = new InstanceFieldAccess();
               c.setS("abc");
               c.accessField();
               System.out.println("In Java:");
               System.out.println("  c.s = \"" + c.getS() + "\"");
           }
           static {
               System.loadLibrary("InstanceFieldAccess");
           }
          
        public void setS(String s)
        {
            this.s = s;
        }
       
        public String getS()
        {
           return s;
        )
          
      }
     
      以下是C语言代码:
     
      #include <jni.h>
      #include <stdio.h>
      #include "InstanceFieldAccess.h" 
     
      JNIEXPORT void JNICALL
      Java_InstanceFieldAccess_accessField(JNIEnv *env, jobject obj)
      {
          jfieldID fid;   /* store the field ID */
          jstring jstr;
          const char *str;
     
         //获取java类实例
          jclass cls = (*env)->GetObjectClass(env, obj);
     
          printf("In C:\n");
     
         //获取java类实例的变量s
          fid = (*env)->GetFieldID(env, cls, "s",
                                   "Ljava/lang/String;");
          if (fid == NULL) {
              return; /* failed to find the field */
          }
     
         //获取变量s的值
          jstr = (*env)->GetObjectField(env, obj, fid);
         //将变量s的值转化为标准c语言能处理的类型
         str = (*env)->GetStringUTFChars(env, jstr, 0);
          if (str == NULL) {
              return; /* out of memory */
          }
          printf("  c.s = \"%s\"\n", str);
          //将str转化为jString 类型
          (*env)->ReleaseStringUTFChars(env, jstr, str);
     
          //修改jString 值为 “123”;
          jstr = (*env)->NewStringUTF(env, "123");
          (*env)->SetObjectField(env, obj, fid, jstr);
}

操作结果为:
In C:
c.s = "abc"
In Java:
c.s = "123"
从该例子来看,我认为,jni处理程序就是一个转化数据的过程,难点在于java与本地语言交流时的数据转化。

分享到:
评论

相关推荐

    Linux标准输入、输出和重定向

    #### 二、标准输入输出示例 - **cat命令**:此命令常用于展示文件内容。如果在命令行中未提供文件名,则cat会从标准输入读取数据并将其输出到标准输出。例如: ```bash $ cat Hello world Hello world Bye ...

    Android下AES加密算法的JNI实现(包含SO文件)

    这包括定义JNI函数接口,使用OpenSSL库(或者其他加密库)来实现AES算法,以及处理输入和输出数据。例如,我们可以定义一个JNI函数原型如下: ```c JNIEXPORT jbyteArray JNICALL Java_...

    Android应用源码串口通信(JNI)例子.zip

    例如,使用`open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY)`打开串口,`cfsetispeed`和`cfsetospeed`设置输入和输出波特率。 5. **数据读写** 通过`read`和`write`函数实现串口数据的读取和发送。读取时需要...

    JNI的MD5算法

    MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,它可以将任意长度的输入转化为固定长度的输出,通常是一个128位的二进制数,通常以32位的十六进制字符串表示。MD5的主要用途是数据完整性校验,确保...

    jni开发技术.pdf

    JNI在实现Java程序与本地系统调用之间的桥梁作用时,可以实现包括输入输出、图形处理、网络通信、线程操作等在内的多种功能。 在文档中提及的示例程序“ReadFile”,展示如何使用JNI从本地系统调用C函数,将文件...

    JNI基础实验一:调用.so文件--友善之臂Tiny210 android 串口/pwm/ADC/LED

    4. **LED控制**:LED控制通常涉及到GPIO(通用输入/输出)接口。JNI代码需要设置GPIO引脚为输出模式,然后通过写入高电平或低电平来控制LED的亮灭。 在"LEDDemo"这个项目中,我们可以看到一个具体的示例,演示了...

    jni需要注意的常见问题

    在使用 JNI 调用 Java 方法时,需要正确地处理 C 和 C++ 的语法差异。 **解决方案**: 1. **C++ 与 C 的调用方式区别**:在 C++ 中,可以直接使用 `JNIEnv` 函数,而无需通过指针调用。但在 C 中,则必须使用 `...

    C入门&&JNI;

    - **输入输出函数**:如`printf`和`scanf`,用于标准输入输出操作,不同格式化字符串对应不同类型的数据。 - **指针**:表示内存地址的变量,`*`用于解引用,`&`获取变量的地址,指针常用于动态内存管理、数组操作...

    JNI综合实验一:LED点亮+IO电平读取

    在压缩包内的文件“20130922 JNI综合实验一:LED点亮+IO电平读取.doc”很可能是实验的详细指南,包含了步骤、代码示例和解释。文件名中的日期可能指示了实验的创建时间,即2013年9月22日。 总结来说,这个实验将...

    Android-一个Frida模块用于跟踪Android应用中JNIAPI的使用情况

    2. **调用参数与返回值记录**:除了函数调用本身,模块还可能记录每个JNI函数调用的输入参数和返回值。这为分析函数行为提供了详细信息,例如,查看特定函数如何处理不同输入,或者检查是否有错误返回值。 3. **...

    android studio使用jni调用opencv库实现图片转换Demo【详细实例源码】

    在Android应用中,你可以在Activity或Service中调用这个`convertImage`方法,传入输入图片路径和期望的输出路径。当方法执行时,JNI接口会触发C++代码的执行,从而完成图片转换。 为了使这个过程更顺畅,你还需要在...

    android jni demo

    - 生成头文件:使用`javah`命令,输入类名,生成`HelloWorld_jni.h`。 - C/C++实现:在`HelloWorld.cpp`中,实现`JNIEXPORT`开头的方法,调用`JNIEnv`指针和`jclass`参数,完成本地方法的逻辑。 - 配置构建:在...

    Android JNI调用c语言加密程序

    2. **防止缓冲区溢出**:加密解密过程中,确保输入和输出大小被正确处理,避免内存安全问题。 3. **选择安全的加密库**:避免使用已知存在漏洞的加密算法,如DES,选择AES等更安全的替代方案。 4. **密钥管理**:...

    Android LED灯5层(app,framework,jni,hal,drivers)源码,可扩展GPIO

    这个LED灯示例提供了完整的源码,帮助开发者深入理解Android系统如何与硬件交互,并且支持GPIO(通用输入/输出)的扩展,适用于2440开发板,但可以进行移植以适应其他开发板。 1. 应用程序层(App): 在这一层,...

    opensl+speex 回音消除 JNI库

    OpenSL ES是针对嵌入式设备优化的音频库,它提供了一套C语言接口,用于处理音频输入、输出、混音、效果处理等任务。在Android上,OpenSL ES可以替代AudioTrack和AudioRecord等API,提供更低的延迟和更高的性能。 2...

    Mediapipe框架在Android上的使用源码

    这通常涉及到在`build.gradle`文件中添加依赖项,并确保你的Android项目配置支持JNI和NDK,因为Mediapipe包含C++代码。 在`TestMediaPipe`这个示例中,可能包含了一些基本的手势识别流程图配置。流程图定义了如何...

    java jna 调用pytorch c++模型推理

    这包括加载Torch Script模型,执行前向传播,以及处理输入和输出数据。 3. **Torch Script**:Torch Script是PyTorch的脚本语言,用于将Python代码转换为独立的、可执行的IR(Intermediate Representation)。这...

    java与android串口通信示例代码

    - 创建输入/输出流:`InputStream in = serialPort.getInputStream(); OutputStream out = serialPort.getOutputStream();` - 开始读写数据:使用`in.read()`读取数据,`out.write()`写入数据。 - 关闭串口:完成...

    Android-运行在Android之上的Go-SDL2示例

    它提供了窗口管理、事件处理、音频输出、图像加载和渲染、以及键盘和鼠标输入等功能。SDL2的一个主要优点是它的跨平台性,可以在Windows、Linux、Mac OS X、Android和iOS等操作系统上运行。 **Android NDK和JNI** ...

Global site tag (gtag.js) - Google Analytics