Jni之在c++中调用java代码
来源:互联网 发布:网络电视没信号怎么调 编辑:程序博客网 时间:2024/06/06 00:27
第一步:完成java代码
public class JniMain {private static int staticIntField=300;static{System.loadLibrary("JniFunc");}public static native JniTest createObject();public static void main(String []args){System.out.println("调用本地方法");JniTest jniObject=createObject();//利用本地方法生成java对象jniObject.callTest();}}
public class JniTest {private int intField;public JniTest(int num){this.intField=num;System.out.println("调用JNItest对象的构造方法:intField="+intField);}public int callByNative(int num){System.out.println("jniTest对象的callByNative调用="+num);return num;}public void callTest(){System.out.println("callTest被调用="+intField);}}
第二步:利用javah命令生成c++头文件
/* DO NOT EDIT THIS FILE - it is machine generated */#include "jni.h"/* Header for class com_jni_JniMain */#ifndef _Included_com_jni_JniMain#define _Included_com_jni_JniMain#ifdef __cplusplusextern "C" {#endif/* * Class: com_jni_JniMain * Method: createObject * Signature: ()Lcom/jni/JniTest; */JNIEXPORT jobject JNICALL Java_com_jni_JniMain_createObject (JNIEnv *, jclass);//由于是static静态方法,所以传的参数为jclass类型#ifdef __cplusplus}#endif#endif
第三步:完成c++代码,要在vs中项目属性里的包含目录中添加jdk的相关c/c++文件的目录
#include "com_jni_JniMain.h"#include<stdio.h>JNIEXPORT jobject JNICALL Java_com_jni_JniMain_createObject(JNIEnv *env, jclass jclassParams){jclass targetClass;jmethodID mid;jobject newObject;jstring helloStr;jfieldID fid;jint staticIntField;jint result;//参数分别指的是包含静态成员的类,成员变量名,成员变量的签名(可以通过javap -s -p 类名命令来获取)printf("本地方法开始!\n");fid=env->GetStaticFieldID(jclassParams,"staticIntField","I");//根据类及成员的字段ID来获取成员变量的值staticIntField=env->GetStaticIntField(jclassParams,fid);printf("获取JniFuncMain类的staticIntField值=%d\n",staticIntField);//获取指定类名的jclass对象targetClass=env->FindClass("com/jni/JniTest");//包名+类名//查找指定的方法的methodID,根据jclass对象、方法名(构造函数的方法名为<init>)、方法签名mid=env->GetMethodID(targetClass,"<init>","(I)V");printf("生成JniTest对象\n");//利用构造函数创建对象、最后为构造函数的参数newObject=env->NewObject(targetClass,mid,100);mid=env->GetMethodID(targetClass,"callByNative","(I)I");result=env->CallIntMethod(newObject,mid,200);fid=env->GetFieldID(targetClass,"intField","I");//设定字段的值env->SetIntField(newObject,fid,result);return newObject;}
从代码来看:要调用静态方法或静态成员变量:首先利用JNIEnv对象来查找到相应的类的jclass类型->然后在获取方法或成员ID,这里利用变量签名和方法签名->然后在利用jclass对象调用方法或对数据进行操作
而使用非静态方法则需要多一个查找并调用构造函数的过程
可以使用javap反编译命令来获取成员或方法签名,实现要先编译java文件
第四步:利用vs的命令提示工具生成dll共享库,利用其cl命令
第五步:执行得到结果
如果是纯c++调用jni则需要自己加载jvm,其余大致相同,不过需多加在一个lib库,如下所示
#include<jni.h>int main(){JNIEnv *env;JavaVM *vm;JavaVMInitArgs vm_args;JavaVMOption options[1];jint res;jclass cls;jmethodID mid;jstring jstr;jclass stringClass;jobjectArray args;//设置java虚拟机选项options[0].optionString="-Djava.class.path=.";vm_args.version=0x00010008;//在jni.h文件中可找到该值vm_args.options=options;vm_args.nOptions=1;vm_args.ignoreUnrecognized=JNI_TRUE;//生成java虚拟机res=JNI_CreateJavaVM(&vm,(void**)&env,&vm_args);cls=env->FindClass("InvocationApiTest");mid=env->GetStaticMethodID(cls,"main","([Ljava/lang/String;)V");jstr=env->NewStringUTF("hello invocationApiTest!");stringClass=env->FindClass("java/lang/String");//获取String类jclass实例args=env->NewObjectArray(1,stringClass,jstr);//创建String数组env->CallStaticVoidMethod(cls,mid,args);//调用main方法vm->DestroyJavaVM();//关闭jvmreturn 0;}
0 0
- 使用JNI在C中调用java代码
- 使用JNI在java中调用C代码
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Jni之在c++中调用java代码
- 安卓jni调用之C代码中调用Java代码
- 使用JNI进行混合编程:在C/C++中调用Java代码
- window下利用JNI在java代码中调用c/c++接口
- 使用JNI进行混合编程:在C/C++中调用Java代码
- 在java中调用c/c++代码的方法(jni)
- 在java中调用c/c++代码的方法(jni)
- 在java中调用c/c++代码的方法(jni)
- 一个初级例子讲述C和CPP在JNI中调用安卓Java代码
- 【转】使用JNI进行混合编程:在C/C++中调用Java代码
- 安卓JNI/NDK开发3(进阶 在C代码中调用java方法)
- 通过JNI接口在Android中调用C/C++代码
- JNI(1) 在java中调用本地c++代码
- SQL Server学习记录之set nocount on
- 在Eclipse里查看Java字节码
- httpd: Could not reliably determine the server's fully qualified domain name
- MIPS 通用寄存器
- Activity总结
- Jni之在c++中调用java代码
- 深入理解Android的startservice和bindservice
- IOS每天15个注意点系列之UI-应用管理
- 权限导致apk安装包安装失败
- 黑马程序员 深入理解 Java中的 流 (Stream)
- Codeforces Round #320 (Div. 2)D. "Or" Game
- Java学习笔记04 异常
- ORACLE触发器详解
- Hadoop中HDFS的设计目标