`
longdick
  • 浏览: 579956 次
  • 性别: Icon_minigender_1
  • 来自: 0
社区版块
存档分类
最新评论

使用JNI集成java与native程序

阅读更多


当我们开始接触JNI但是还不熟悉的时候,也许会这样几个问题:

  1. Java程序和native程序的数据类型通常是不一样的,它们怎么相互映射的呢?
  2. 怎么在native方法中访问java方法传递过来的数据呢?
  3. 在native方法中可以创建java对象吗?
  4. 如何把结果返回给调用它的java方法?

读完本文你将会明白如上问题的来龙去脉。首先我在重复一下如何编写JNI相关的应用程序,我们必须在java方法中声明一个native的方法,比如 public native String getLine(String prompt);这个方法具有的两个特点是,引入了关键字native,它的意思是这个方法的实现由其他的语言实现,比如c/c++等。另外这个方法是以 分号结尾的,表明这个方法不包括实现。我们在上篇文章已经知道使用javah命令可以得到我们需要的header文件。下面给出java程序和相关的.h 文件的代码

//Prompt.java
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");
}
}

//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

我们可以看到在Prompt.h文件中定义了我们要实现的函数的原型,我们主要关心两点一个是方法名称另一个是方法的参数,方法的名称为Java_Prompt_getLine,它是由如下四部分组成

看看方法的参数,由三个参数组成分别是JNIEnv *, jobject, jstring。JNIEnv是一个JNI接口指针,它事实上是由函数表组成的,我们可以使用JNIEnv来访问java对象。jobject是当前类的 的引用,想当与java中的this。最后一个参数是jstring,代表了我们java方法中的String prompt。

在编写native方法的时候,无论是java基本类型还是对象我们都不能在c/c++中直接使用,必须要转成相对应得类型,下面给出基本数据类型的对应关系。

 

Java Type Native Type Size in bits
boolean jboolean 8, unsigned
byte jbyte 8
char jchar 16, unsigned
short jshort 16
int jint 32
long jlong 64
float jfloat 32
double jdouble 64
void void n/a

关于java对象,JNI都是把它映射为jobject,为了减少编程的错误可能性,同时从jobject中实现了一些子类型,比如jstring等。

下面我们讲述,如何在native方法中访问java方法的参数,如何在native方法中创建java对象。我们必须清楚地知道,在访问java参数的 时候,首先要把它转换为相应的类型,比如参数String prompt在.h文件中为jstring。但是在实现这个方法的时候,我们不能直接对jstring进行操作,因为它与char *是不同的,我们要通过JNIEnv提供的方法把它转换为char *。比如
char buf[128];
const char *str = env->GetStringUTFChars(prompt, 0);
printf("%s", str);
注 意一点,我们必须要主动释放我们得到的char *,否则会造成内存泄漏。释放的方法还是通过JNIenv提供的方法,(*env).ReleaseStringUTFChars(prompt, str);。JNIEnv同样提供了构造String的方法,使得我们可以返回给调用者一个String类型的返回值
gets(buf);
return (*env).NewStringUTF(buf);

下面给出native实现的源代码(c++代码)
#include <stdio.h>
#include <jni.h>
#include "Prompt.h"

JNIEXPORT jstring JNICALL
Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
{
char buf[128];
const char *str = env->GetStringUTFChars(prompt, 0);
printf("%s", str);
(*env).ReleaseStringUTFChars(prompt, str);
gets(buf);
return (*env).NewStringUTF(buf);
}
在VC++中,你可以创建一个dll工程,最后把得到的prompt.dll方到Prompt.class的目录,运行java Prompt,系统就会提示你输入一行字符。输入回车后则可以回显到控制台。

分享到:
评论

相关推荐

    Java程序设计之swt教程.pdf

    SWT(Standard Widget Toolkit)即标准小窗口工具箱,是IBM公司推出的一...SWT由JNI(Java Native Interface, Java 本机接口)调用操作系统的内部API,因此运行速度快,能够获得与操作系统的内部应 用程序相同的外观。

    windows下 eclipse+ndk编译及使用jni示例

    3.) 在Java Activity代码中添加对这个jni的调用 (本例中是MainActivity.java ): static { System.loadLibrary("main_jni"); } 4.) 在调用者Activity中定义函数 native int SomeFunc(); 5.) 在activity中调用 @...

    android studio 下集成ndk 通过java jni调用c

    自己在android studio 环境下集成ndk 、 cmake 、LLDB 等插件 开发的一个demo ; 可以直接debug到c端代码,eclipse一般追踪不到,遇到c端出问题手机直接一个crash,,,想要了解android studio 下如何进行c 开发的...

    Android-native-examples:该项目展示了如何使用JNI(Java本机接口)在Android App上集成C源代码-Show source code

    该项目显示了如何使用JNI(Java本机接口)在Android App上集成C源代码。 在这种情况下,我已经使用纯Java和C代码实现了Fibonacci和阶乘算法(递归和迭代版本),以比较它们的性能。 经过几次执行后,有可能观察到本...

    swt自学资料.rar

    SWT(Standard Widget Toolkit)即标准小窗口工具箱,是IBM公司推出的一种...SWT由JNI(Java Native Interface,Java本机接口)调用操作系统的内部API,因此运行速度快,能够获得与操作系统的内部应用程序相同的外观。

    java开源包8

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    JAVA上百实例源码以及开源项目源代码

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    JAVA上百实例源码以及开源项目

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java开源包4

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包101

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包11

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包6

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包9

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包5

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包10

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包1

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    java开源包3

    LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...

    jni-algorithm:jni实现的多数算法

    jni-algorithm 持续更新: jni实现的多个算法 算法1:NativeImageUtils:public static native int[] argbToBitmapColors(byte[] srcData); RGB或者ARGB格式转码成像素点 之后由像素点生成bitmap 转码时间:04-19 15...

    java-native:测试使用mvn构建多平台本机Java 1.8 Maven软件包

    该项目旨在说明如何使用和少量构建Java 1.8本机(适用于win32-x86-64,linux-x86-64和darwin)maven多包。 例如,由于有了SWIG,您有了一个跨平台的C ++库和一个JNI包装器。 然后,您想提供一个跨平台的Maven软件包...

Global site tag (gtag.js) - Google Analytics