`

基本JNI调用技术(c/c++与java互调)

 
阅读更多

http://blog.csdn.net/zjsjava/article/details/2458822

 

虽不是很详细,但步骤都已相当明确了的.

 一. C/C++ 调用Java
C/C++ 中调用 Java 的方法一般分为五个步骤:初始化虚拟机、获取类、创建类对象、调用方法和退出虚拟机。
1.  初始化虚拟机
代码如下:
    JNIEnv *env;
     JavaVM *jvm;
    JavaVMInitArgs vm_args;
    JavaVMOption options[3];
    int res;
    //设置参数
options[0].optionString = "-Djava.compiler=NONE";
//classpath有多个时,UNIX下以“:”分割。
    options[1].optionString = "-Djava.class.path=.";
    options[2].optionString = "-verbose:jni";
 
    vm_args.version = JNI_VERSION_1_4;
    vm_args.nOptions = 3;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = JNI_TRUE;
    res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
     if (res >= 0)
{
     //创建虚拟机成功
}
一个应用程序只需要一个虚拟机,但是每个线程需要自己的虚拟机运行环境。我们从一个虚拟机获取多个当前线程的运行环境,代码如下:
int result=0;
result=jvm->AttachCurrentThread( reinterpret_cast<void**>( &env ), 0 );
if(result>=0)
{
     //获取运行环境成功
}
当线程退出时,需要释放本线程使用的运行环境。
jvm->DetachCurrentThread();
2 获取类
在进行方法调用之前,需要先获取相应的类,类名称必须包括包名,其中的“.”用“/”代替。
jclass JavaClass;
JavaClass = env->FindClass("com/test/TestInterface");
   if(JavaClass != 0)
   {
            //获取成功
   }
3 创建类对象
如果需要调用的方法静态方法,则可以跳过本步骤。反之,则需要构造该对象。构造对象是通过调用类的构造函数来实现的,构咱函数的方法声明为<init>, GetMethodID方法的参数在下一步骤详细说明。
jobject obj;
jmethodID ctor;
ctor = env->GetMethodID(JavaClass,"<init>","()V");
if(ctor != 0)//获取方法成功
   {
         obj = env->NewObject(JavaClass, ctor);
   }
4 调用方法
调用一个方法需要两个步骤:获取方法句柄和调用方法。
jmethodID methodID = env->GetMethodID( JavaClass, "setTest","(I)V");
if(methodID!=0)//获取方法成功
{
env->CallVoidMethod( obj, methodID,12);
}
GetStaticMethodID是用来获取静态方法的定义,GetMethodID则是获取非静态的方法定义。他们传入参数的参数依次为:类定义、方法名称和方法的定义,方法的定义可以用jdk中带的javap工具反编译class文件获取,其格式如下:
public void setTest(int inTest);
  Signature: (I)V
Signature后面的内容就是方法的定义。
CallVoidMethod是对获取的方法进行调用,JNI接口中提供了一系列的同类 方法,包括静态方法的调用函数(如:CallStaticXXXMethod)和非静态的方法(如:CallXXXMethod),其中XXX表示的不同 方法返回类型,包括int、object等等。
5 退出虚拟机
退出虚拟机调用方法如下:
jvm->DestroyJavaVM();
在JNI接口定义中,只有最后一个线程退出时,该方法才会返回,但是我只用一个线程,调用该方法也无法返回。故此建议系统退出时执行该方法,或者整个程序退出时,让虚拟机自己释放。
[注意]:
在处理中文字符串时,需要注意Java的char是双字节的,采用Unicode编码,在和C++中的char转换时,需要用到系统API:WideCharToMultiByte和MultiByteToWideChar。
注意对运行环境中对象引用时的释放,以免引起内存泄漏。
jstring str;
wchar_t *w_buffer =(wchar_t *)env->GetStringChars(str,0);
env->ReleaseStringChars(str,(const unsigned short *)w_buffer);
6 处理异常
C/C++中调用Java时,一定要捕获并处理Java方法抛出的异常信息,否则可能导致C/C++进程的核心转储(Core Dump)。
异常应在每个方法调用后检查:
msg = (jstring)env->CallObjectMethod(obj, mid);
        if (env->ExceptionOccurred())
        {
           env->ExceptionDescribe();         
           env->ExceptionClear();
           return 0;
        }
二.Java 调用C/C++
Java调用C/C++时,遵循几个步骤:
1、  用Java native 关键字声明方法为本地方法(非Java语言实现)。
2、  编译该声明类,得到XXX.class文件。
3、  用“javah –jni XXX”命令从该class文件生成C语言头文件(XXX.h)。
4、  采用C语言实现该头文件声明的方法,将实现类编译成库文件(libXXX.so)。
5、  在Java程序中使用System.loadLibrary(XXX)加载该库文件(需要设置-Djava.library.path环境变量指向该库文件存放路径)。
6、  即可象调用Java方法一样,调用native方式声明的本地方法。
分享到:
评论

相关推荐

    JNI技术手册 c/c++调用java

    ### JNI技术手册:C/C++与Java互调详解 #### 一、JNI技术概览 **JNI(Java Native Interface)** 是Java平台的一部分,它允许Java代码与其他语言写的代码进行交互,尤其是C和C++。JNI是Java与本地代码之间沟通的...

    Qt for Android 用JNI来使C++和Java互调(目前最新版全网只有这个可用)

    "Qt for Android 用JNI来使C++和Java互调"的主题揭示了如何利用JNI(Java Native Interface)技术在Qt与Android原生系统之间建立桥梁,实现两者的交互。以下将详细介绍这一过程。 首先,Qt for Android是Qt项目的一...

    JNI java c/c++技术手册

    本手册专注于介绍如何使用JNI来实现Java与C/C++之间的互调。 一、JNI基础知识 1. JNI接口定义:JNI提供了丰富的函数接口,如NewGlobalRef、FindClass、GetMethodID等,用于在Java和本地代码之间建立桥梁。 2. 本地...

    c++和java互调代码示例

    当我们需要在Java应用程序中调用C++函数或者反之时,JNI就扮演了关键角色。 1. **JNI基础知识**: - JNI头文件:在C++代码中,我们需要包含jni.h头文件,这是JNI的核心,定义了各种函数原型和数据类型。 - 导入库...

    ocos2d-x 通过JNI实现c/c++和Android的java层函数互调

    cocos2d-x 通过JNI实现c/c++和Android的java层函数互调, 本文主要实现两个功能: (1)通过Android sdk的API得到应用程序的包名(PackageName),然后传递给c++层函数。 (2)通过c++函数调用Android的java层函数,显示一...

    关于JNI的小例子 实现java与C++的方法互调

    本教程将通过一个小例子,详细介绍如何使用JNI实现Java与C++方法的互调。 首先,我们需要在Java层定义一个native方法。在Java中,我们可以使用`native`关键字声明一个方法,但不提供具体实现,如下所示: ```java ...

    cocos2d-x 通过JNI实现c/c++和Android的java层函数互调-源码

    本主题聚焦于如何通过JNI(Java Native Interface)来实现在Cocos2d-x中调用Java层的函数,以及反之在Java层调用C++代码。下面我们将深入探讨这一技术。 JNI是Java平台的一部分,它为开发者提供了一种方式来编写...

    使用JNI进行JAVA和C++之间的互调

    在这个场景中,你提到的是使用JNI在VS2013环境下,将Java与C++进行互调。 首先,让我们了解一下JNI的基本工作原理: 1. **定义Java方法:** 在Java类中,你需要声明一个native方法,这意味着它的实现将在本地代码...

    ndk源码基于eclipse开发c/c++/java

    5. **Java与C/C++互调**: - 在Java代码中,通过`System.loadLibrary("library_name")`加载本地库。 - 使用`native`关键字声明方法,并使用`javah`命令生成对应的C/C++头文件。 - 在C/C++代码中实现这些方法,...

    Android Studio3.0开发JNI流程------C++调用Java以及Java调用C++,C++/Java互相调用

    在Android应用开发中,JNI(Java Native Interface)是一种技术,允许Java代码和其他语言写的代码进行交互。JNI在Android系统中扮演着重要的角色,特别是在需要高效计算或者利用硬件特性时,如游戏开发、图像处理和...

    JNI(c++与Java互调)cocos2d-x_3.x和android studio 3.0

    3. **Java与C++互调**:在Java代码中,使用`System.loadLibrary("your_library_name")`加载本地库。然后,通过`native`关键字声明方法,这些方法将在C++中实现。C++中,使用`JNIEXPORT`和`JNICALL`宏定义Java方法...

    Cocos2d-x与Android交互(c++与java互调),与IOS交互(c++与objective c混编)

    Cocos2d-x与Android交互(c++与java互调),与IOS交互(c++与objective c混编) 具体的代码请下载这个文件,里面有更详细的jni使用方法,包括传递基本数据类型,返回基本数据类型的值,及类型的转换。

    3.jni_c++调用java中的方法

    总的来说,JNI提供了C++与Java交互的桥梁,而C++与JavaScript的互调则依赖于特定的运行环境和技术栈。理解这些机制对于开发跨平台应用或优化性能至关重要。在实际项目中,确保正确处理内存管理、异常处理以及线程...

    JNI编程(二) —— 让C++和Java相互调用(2)

    在C++代码编译成动态链接库后,Java程序加载这个库,就可以调用C++中的`sayHello()`方法了。这种互调的能力使得开发者可以利用C++的高性能特性处理CPU密集型任务,同时保持Java的跨平台优势。 除了基本的调用机制,...

    JNI应用实例(java、C++互调)

    实例1: 1)使用javah 生成.h文件 2)根据.h文件,编写.cpp源程序。 实例2: 1)演示了java调用c++,以及c++调用java。 2)java 与 c++ 间,通过复杂数据类型(Vector)作为参数来传递数据。

    NDK中JAVA和C互相调用

    NDK提供了一种方式让Java代码能够与本地C或C++代码进行交互,这主要通过JNI(Java Native Interface)实现。本文将详细介绍如何在NDK中实现JAVA和C的互相调用。 首先,让我们理解JNI的基本概念。JNI是Java平台的...

    JNI完全技术手册 带完整书签

    Chap12:基本JNI调用技术(c/c++与java互调) 93 Chap13:JNI的c代码中,另外一个线程获取 JNIEnv. 96 chap 14:当JNI遇到多线程--java对象如何被C++中的多个线程访问?. 97 chap 15:JNI在多线程中的应用... 101 ...

    JNI语法.zip

    JNI在Android开发中尤其重要,特别是在需要利用硬件加速、底层库或者提高性能的应用场景下,开发者会借助C/C++来编写部分代码,然后通过JNI与Java层进行通信。 在"JNI语法.zip"这个压缩包中,包含两个子文件,分别...

    C和Java互调示例

    JNI是Java平台的标准接口,它为Java代码提供了与本地代码(如C/C++)交互的能力。通过JNI,Java程序可以调用C函数,反之亦然。要使用JNI,首先需要在Java代码中声明本地方法,并使用`native`关键字标记。然后使用`...

Global site tag (gtag.js) - Google Analytics