JNI 返回结构体参数_第1页
JNI 返回结构体参数_第2页
JNI 返回结构体参数_第3页
JNI 返回结构体参数_第4页
JNI 返回结构体参数_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JNI 返回结构体参数返回结构体参数 JNIJavaCC C 如何使用 JNI 的一些基本方法和过程在网上多如牛毛 如果你对 Jni 不甚了解 不知道 Jni 是做什么 的 如何建立一个基本的 jni 程序 或许可以参考下面下面这些文章 利用 VC 6 0 实现 JNI 的最简单的例子 JNI 入门教程之 HelloWorld 篇 SUN JNI Tutorial 这些资料的例子中 大多数只是输入一些简单的参数 获取没有参数 而在实际的使用过程中 往 往需要对参数进行处理转换 才可以被 C C 程序识别 比如我们在 C 中有一个结构 Struct DiskInfo 需要传递一个类似于 DiskInfo pDiskInfo 的参数 类似于在 C 这样参数如何传递到 Java 中呢 下面我们就来讨论 C 到 Java 中方法的一些常见参数的转换 定义 Native Java 类 如果你习惯了使用 JNI 你就不会觉得它难了 既然本地方法是由其他语言实现的 它们在 Java 中 没有函数体 但是 所有本地代码必须用本地关键词声明 成为 Java 类的成员 假设我们在 C 中有这么一个结构 它用来描述硬盘信息 Java 代码代码 1 硬盘信息 2 struct 3 char name 256 4 int serial 5 DiskInfo 那么我们需要在 Java 中定义一个类来与之匹配 声明可以写成这样 Java 代码代码 1 class DiskInfo 2 名字 3 public String name 4 5 序列号 6 public int serial 7 在这个类中 申明一些 Native 的本地方法 来测试方法参数的传递 分别定义了一些函数 用来传 递结构或者结构数组 具体定义如下面代码 Java 代码代码 1 定义本地方法 2 输入常用的数值类型 Boolean Byte Char Short Int Float Double 3 public native void displayParms String showText int i boolean bl 4 5 调用一个静态方法 6 public native int add int a int b 7 8 输入一个数组 9 public native void setArray boolean blList 10 11 返回一个字符串数组 12 public native String getStringArray 13 14 返回一个结构 15 public native DiskInfo getStruct 16 17 返回一个结构数组 18 public native DiskInfo getStructArray 编译生成 C C 头文件 定义好了 Java 类之后 接下来就要写本地代码 本地方法符号提供一个满足约定的头文件 使用 Java 工具 Javah 可以很容易地创建它而不用手动去创建 你对 Java 的 class 文件使用 javah 命令 就会为你生成一个对应的 C C 头文件 1 在控制台下进入工作路径 本工程路径为 E work java workspace JavaJni 2 运行 javah 命令 javah classpath E work java workspace JavaJni com sundy jnidemo ChangeMethodFromJni 本文生成的 C C 头文件名为 com sundy jnidemo ChangeMethodFromJni h 在 C C 中实现本地方法 生成 C C 头文件之后 你就需要写头文件对应的本地方法 注意 所有的本地方法的第一个参数 都是指向 JNIEnv 结构的 这个结构是用来调用 JNI 函数的 第二个参数 jclass 的意义 要看方法 是不是静态的 static 或者实例 Instance 的 前者 jclass 代表一个类对象的引用 而后者是 被调用的方法所属对象的引用 返回值和参数类型根据等价约定映射到本地 C C 类型 如表 JNI 类型映射所示 有些类型 在本 地代码中可直接使用 而其他类型只有通过 JNI 调用操作 表 A Java 类型 本地类型 描述 boolean jboolean C C 8 位整型 byte jbyte C C 带符号的 8 位整型 char jchar C C 无符号的 16 位整型 short jshort C C 带符号的 16 位整型 int jint C C 带符号的 32 位整型 long jlong C C 带符号的 64 位整型 e float jfloat C C 32 位浮点型 double jdouble C C 64 位浮点型 Object jobject 任何 Java 对象 或者没有对应 java 类型的对象 Class jclass Class 对象 String jstring 字符串对象 Object jobjectArray 任何对象的数组 boolean jbooleanArray 布尔型数组 byte jbyteArray 比特型数组 char jcharArray 字符型数组 short jshortArray 短整型数组 int jintArray 整型数组 long jlongArray 长整型数组 float jfloatArray 浮点型数组 double jdoubleArray 双浮点型数组 JNI 类型映射 使用数组 JNI 通过 JNIEnv 提供的操作 Java 数组的功能 它提供了两个函数 一个是操作 java 的简单型数组 的 另一个是操作对象类型数组的 因为速度的原因 简单类型的数组作为指向本地类型的指针暴露给本地代码 因此 它们能作为常 规的数组存取 这个指针是指向实际的 Java 数组或者 Java 数组的拷贝的指针 另外 数组的布置 保证匹配本地类型 为了存取 Java 简单类型的数组 你就要要使用 GetXXXArrayElements 函数 见表 B XXX 代表 了数组的类型 这个函数把 Java 数组看成参数 返回一个指向对应的本地类型的数组的指针 表 B 函数 Java 数组类型 本地类型 GetBooleanArrayElements jbooleanArray jboolean GetByteArrayElements jbyteArray jbyte GetCharArrayElements jcharArray jchar GetShortArrayElements jshortArray jshort GetIntArrayElements jintArray jint GetLongArrayElements jlongArray jlong GetFloatArrayElements jfloatArray jfloat GetDoubleArrayElements jdoubleArray jdouble JNI 数组存取函数 当你对数组的存取完成后 要确保调用相应的 ReleaseXXXArrayElements 函数 参数是对应 Java 数组和 GetXXXArrayElements 返回的指针 如果必要的话 这个释放函数会复制你做的任何变化 这样它们就反射到 java 数组 然后释放所有相关的资源 为了使用 java 对象的数组 你必须使用 GetObjectArrayElement 函数和 SetObjectArrayElement 函 数 分别去 get set 数组的元素 GetArrayLength 函数会返回数组的长度 使用对象 JNI 提供的另外一个功能是在本地代码中使用 Java 对象 通过使用合适的 JNI 函数 你可以创建 Java 对象 get set 静态 static 和实例 instance 的域 调用静态 static 和实例 instance 函 数 JNI 通过 ID 识别域和方法 一个域或方法的 ID 是任何处理域和方法的函数的必须参数 表 C 列出了用以得到静态 static 和实例 instance 的域与方法的 JNI 函数 每个函数接受 作为 参数 域或方法的类 它们的名称 符号和它们对应返回的 jfieldID 或 jmethodID 表 C 函数 描述 GetFieldID 得到一个实例的域的 ID GetStaticFieldID 得到一个静态的域的 ID GetMethodID 得到一个实例的方法的 ID GetStaticMethodID 得到一个静态方法的 ID 域和方法的函数 如果你有了一个类的实例 它就可以通过方法 GetObjectClass 得到 或者如果你没有这个类的实例 可以通过 FindClass 得到 符号是从域的类型或者方法的参数 返回值得到字符串 如表 D 所示 表 D Java 类型 符号 boolean Z byte B char C short S int I long L float F double D void V objects 对象 Lfully qualified class name L 类名 Arrays 数组 array type 数组类型 methods 方法 argument types return type 参数类型 返回类型 确定域和方法的符号 下面我们来看看 如果通过使用数组和对象 从 C 中的获取到 Java 中的 DiskInfo 类对象 并返 回一个 DiskInfo 数组 Java 代码代码 1 返回一个结构数组 返回一个硬盘信息的结构数组 2 JNIEXPORT jobjectArray JNICALL Java com sundy jnidemo ChangeMethodFromJni getStructArra y 3 JNIEnv env jobject obj 4 5 申明一个 object 数组 6 jobjectArray args 0 7 8 数组大小 9 jsize len 5 10 11 获取 object 所属类 一般为 ava lang Object 就可以了 12 jclass objClass env FindClass java lang Object 13 14 新建 object 数组 15 args env NewObjectArray len objClass 0 16 17 下面为获取到 Java 中对应的实例类中的变量 18 19 获取 Java 中的实例类 20 jclass objectClass env FindClass com sundy jnidemo DiskInfo 21 22 获取类中每一个变量的定义 23 名字 24 jfieldID str env GetFieldID objectClass name Ljava lang String 25 序列号 26 jfieldID ival env GetFieldID objectClass serial I 27 28 给每一个实例的变量付值 并且将实例作为一个 object 添加到 objcet 数组中 29 for int i 0 i SetObjectField obj str env NewStringUTF my name is D 34 env SetObjectField obj str jstr 35 env SetShortField obj ival 10 36 37 添加到 objcet 数组中 38 env SetObjectArrayElement args i obj 39 40 返回 object 数组 41 return args 42 43 44 45 46 全部的 C C 方法实现代码如下 47 48 49 一缕阳光 sundy 版权所有 保留所有权利 50 51 52 53 TODO Jni 中一个从 Java 到 C C 参数传递测试类 54 55 author 刘正伟 sundy 56 see 57 see mailto sundy26 58 version 1 0 59 since 2005 4 30 60 61 修改记录 62 63 日期 修改人 描述 64 65 66 67 68 69 JniManage cpp 定义 DLL 应用程序的入口点 70 71 package com sundy jnidemo 72 include stdafx h 73 74 include 75 include 76 include jni h 77 include jni md h 78 79 include head Base h 80 include head wmi h 81 include head com sundy jnidemo ChangeMethodFromJni h 通过 javah jni javactransfer 生成 82 include 83 include stdlib h 84 include string h 85 86 pragma comment lib BaseInfo lib 87 pragma comment lib jvm lib 88 硬盘信息 89 struct 90 char name 256 91 int serial 92 DiskInfo 93 BOOL APIENTRY DllMain HANDLE hModule 94 DWORD ul reason for call 95 LPVOID lpReserved 96 97 98 LPTSTR strName new CHAR 256 99 GetHostName strName 100 printf s n strName 101 delete strName 102 103 return TRUE 104 105 将 jstring 类型转换成 windows 类型 106 char jstringToWindows JNIEnv env jstring jstr 107 将 windows 类型转换成 jstring 类型 108 jstring WindowsTojstring JNIEnv env char str 109 110 主函数 111 BOOL WINAPI DllMain HANDLE hHandle DWORD dwReason LPVOID lpReserved 112 113 return TRUE 114 115 输入常用的数值类型 Boolean Byte Char Short Int Float Double 116 JNIEXPORT void JNICALL Java com sundy jnidemo ChangeMethodFromJni displayParms 117 JNIEnv env jobject obj jstring s jint i jboolean b 118 119 const char szStr env GetStringUTFChars s 0 120 printf String s n szStr 121 printf int d n i 122 printf boolean s n b JNI TRUE true false 123 env ReleaseStringUTFChars s szStr 124 125 126 调用一个静态方法 只有一个简单类型输出 127 JNIEXPORT jint JNICALL Java com sundy jnidemo ChangeMethodFromJni add 128 JNIEnv env jobject jint a jint b 129 130 int rtn int a b 131 return jint rtn 132 133 134 输入一个数组 这里输入的是一个 Boolean 类型的数组 135 JNIEXPORT void JNICALL Java com sundy jnidemo ChangeMethodFromJni setArray 136 JNIEnv env jobject jbooleanArray ba 137 138 jboolean pba env GetBooleanArrayElements ba 0 139 jsize len env GetArrayLength ba 140 int i 0 141 change even array elements 142 for i 0 i ReleaseBooleanArrayElements ba pba 0 148 149 150 返回一个字符串数组 151 JNIEXPORT jobjectArray JNICALL Java com sundy jnidemo ChangeMethodFromJni getStringArra y 152 JNIEnv env jobject 153 154 jstring str 155 jobjectArray args 0 156 jsize len 5 157 char sa Hello world JNI is fun 158 int i 0 159 args env NewObjectArray len env FindClass java lang String 0 160 for i 0 i NewStringUTF sa i 163 env SetObjectArrayElement args i str 164 165 return args 166 167 168 返回一个结构 这里返回一个硬盘信息的简单结构类型 169 JNIEXPORT jobject JNICALL Java com sundy jnidemo ChangeMethodFromJni getStruct 170 JNIEnv env jobject obj 171 172 下面为获取到 Java 中对应的实例类中的变量 173 174 获取 Java 中的实例类 175 jclass objectClass env FindClass com sundy jnidemo DiskInfo 176 177 获取类中每一个变量的定义 178 名字 179 jfieldID str env GetFieldID objectClass name Ljava lang String 180 序列号 181 jfieldID ival env GetFieldID objectClass serial I 182 183 184 给每一个实例的变量付值 185 env SetObjectField obj str env NewStringUTF my name is D 186 env SetShortField obj ival 10 187 188 return obj 189 190 191 返回一个结构数组 返回一个硬盘信息的结构数组 192 JNIEXPORT jobjectArray JNICALL Java com sundy jnidemo ChangeMethodFromJni getStructArra y 193 JNIEnv env jobject obj 194 195 申明一个 object 数组 196 jobjectArray args 0 197 198 数组大小 199 jsize len 5 200 201 获取 object 所属类 一般为 ava lang Object 就可以了 202 jclass objClass env FindClass java lang Object 203 204 新建 object 数组 205 args env NewObjectArray len objClass 0 206 207 下面为获取到 Java 中对应的实例类中的变量 208 209 获取 Java 中的实例类 210 jclass objectClass env FindClass com sundy jnidemo DiskInfo 211 212 获取类中每一个变量的定义 213 名字 214 jfieldID str env GetFieldID objectClass name Ljava lang String 215 序列号 216 jfieldID ival env GetFieldID objectClass serial I 217 218 给每一个实例的变量付值 并且将实例作为一个 object 添加到 objcet 数组中 219 for int i 0 i SetObjectField obj str env NewStringUTF my name is D 224 env SetObjectField obj str jstr 225 env SetShortField obj ival 10 226 227 添加到 objcet 数组中 228 env SetObjectArrayElement args i obj 229 230 返回 object 数组 231 return args 232 233 234 235 将 jstring 类型转换成 windows 类型 236 char jstringToWindows JNIEnv env jstring jstr 237 238 int length env GetStringLength jstr 239 const jchar jcstr env GetStringChars jstr 0 240 char rtn char malloc length 2 1 241 int size 0 242 size WideCharToMultiByte CP ACP 0 LPCWSTR jcstr length rtn length 2 1 NU LL NULL 243 if size ReleaseStringChars jstr jcstr 246 rtn size 0 247 return rtn 248 249 将 windows 类型转换成 jstring 类型 250 jstring WindowsTojstring JNIEnv env char str 251 252 jstring rtn 0 253 int slen strlen str 254 unsigned short buffer 0 255 if slen 0 256 rtn env NewStringUTF str 257 else 258 259 int length MultiByteToWideChar CP ACP 0 LPCSTR str slen NULL 0 260 buffer unsigned short malloc length 2 1 261 if MultiByteToWideChar CP ACP 0 LPCSTR str slen LPWSTR buffer length 0 262 rtn env NewString jchar buffer length 263 264 if buffer 265 free buffer 266 return rtn 267 268 269 Java 测试 native 代码 270 这没有什么多说的 看代码吧 271 主测试

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论