java与c/c++之间的数据交互
原创
©著作权归作者所有:来自51CTO博客作者4562xse3460的原创作品,请联系作者获取转载授权,否则将追究法律责任
java与c/c++之间的数据交互有这样几种情况:java和c/c++之间基本数据类型的交互,java向c/c++传递对象类型,c/c++向java返回对象类型,c/c++调用java类。
1、java和c/c++之间基本数据类型的交互
对于基本数据类型,java和c是相互对应的,所以可以直接使用。它们的对应关系为
Java类型
| C/C++类型
| 字节(bit)
|
boolean
| jboolean
| 8, unsigned
|
byte
| jbyte
| 8
|
char
| jchar
| 16, unsigned
|
short
| jshort
| 16
|
int
| jint
| 32
|
float
| jfloat
| 32
|
double
| jdouble
| 64
|
long
| jlong
| 64
|
2、Java调用C++
要想让java调用C++,必须让C++函数按着命名规则来。
命名规则为返回值 Java_包路径_类名_函数名(JNIEnv* env,jobject obj);对应如下:
JNIEXPORT jboolean JNICALL Java_com_hook_HookWrap_SetMetadataFilePath
(JNIEnv *, jobject, jstring);
com_hook是包名com.hook
HookWrap是类名
SetMetadataFilePath是函数名
下面是com_hook_HookWrap.h文件
#include <jni.h>
#ifndef _Included_com_hook_HookWrap
#define _Included_com_hook_HookWrap
#ifdef __cplusplus
extern "C"{
#endif
JNIEXPORT jboolean JNICALL Java_com_hook_HookWrap_SetMetadataFilePath
(JNIEnv *, jobject, jstring);
const char* GetMetadataFilePath();
int HaveMetadataFilePath();
#ifdef __cplusplus
}
#endif
下面是com_hook_HookWrap.c文件
#include "com_hook_HookWrap.h"
#include <stdlib.h>
static char g_MetadataFilePath[512] = {0};
#ifdef __cplusplus
extern "C"{
#endif
JNIEXPORT jboolean JNICALL Java_com_hook_HookWrap_SetMetadataFilePath
(JNIEnv *env, jobject obj, jstring jsResPath)
{
if(!jsResPath)
{
return JNI_FALSE;
}
#ifdef __cplusplus
const char* cstr = (env)->GetStringUTFChars(jsResPath, 0);
#else
const char* cstr = (*env)->GetStringUTFChars(env, jsResPath, 0);
#endif
if(!cstr)
{
return JNI_FALSE;
}
strcpy(g_MetadataFilePath, cstr);
#ifdef __cplusplus
(env)->ReleaseStringUTFChars(jsResPath, cstr);
#else
(*env)->ReleaseStringUTFChars(env, jsResPath, cstr);
#endif
return JNI_TRUE:
}
#ifdef __cplusplus
}
#endif
const char* GetMetadataFilePath()
{
if(HaveMetadataFilePath() == 0)
{
return NULL:
}
return g_MetadataFilePath;
}
int HaveMetadataFilePath()
{
if(g_MetadataFilePath[0] == 0)
{
return 0;
}
return 1;
}
这里的jstring不能直接在C/C++程序中使用,需要转换成char*。重要的一点是,在使用完char*之后,一定要记得将其释放,以免发生内存泄漏。
const char* cstr = (env)->GetStringUTFChars(jsResPath, 0); //把jstring转化成char*
(env)->ReleaseStringUTFChars(jsResPath, cstr); //释放变量
下面是Android端的HookWrap.java文件
package com.hook;
import java.io.File;
import android.os.Build;
import android.util.Log;
public class HookWrap
{
//在android端调用C++端的这个方法,传入path
private native boolean SetMetadataFilePath(String strMetadataFilePath);
}