#include "tools_EncryptLib.h"
#include <iostream>
#include "yxyDES.h"
#include <string>using namespace std; //功能:读取文件得到密钥;
string getKey() {
char fileName[] = "C:\\key.txt";
ifstream in(fileName);
string line;
getline(in, line);
return line;
}//功能:将Java的byte数组转换为C char *;
char * jbyteArrayToChar(JNIEnv * env, jbyteArray bytes)
{
char * rtn = NULL;
jsize len = env-> GetArrayLength(bytes);
printf("读取数据长度完成\r\n");
jbyte * arrayBody = env-> GetByteArrayElements(bytes,0);
if(len > 0)
{
rtn = new char[len+1];//(char *)malloc(len+1);
memcpy(rtn, arrayBody, len);
rtn[len]=0;
}
printf("拷贝数据完成\r\n");
env-> ReleaseByteArrayElements(bytes, arrayBody, 0);
printf("释放数据完成\r\n");
return rtn;
} jstring stoJstring(JNIEnv* env, const char* pat)
{
jclass strClass = env->FindClass("Ljava/lang/String;");
jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(pat));
env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
jstring encoding = env->NewStringUTF("utf-8");
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
} JNIEXPORT jstring JNICALL Java_tools_EncryptLib_encrypt
(JNIEnv * env, jobject obj, jbyteArray data, jbyteArray key) {
char* pKey = jbyteArrayToChar(env, key);
char* pData = jbyteArrayToChar(env, data);
printf("读取数据完成\r\n");
yxyDES* my_des = new yxyDES();
my_des->InitializeKey(pKey,false);
my_des->EncryptAnyLength(pData,false);
printf("加密数据完成\r\n");
jstring ret = stoJstring(env, my_des->GetCiphertextAnyLength());
printf("数据格式转换完成\r\n"); //当运行到这里的时候,有时候jvm会崩溃掉,不知道是因何原因
delete[] pKey;
pData = NULL;
delete[] pData;
pData = NULL;
delete my_des;
my_des = NULL;
printf("释放内存完成\r\n");
return ret;
}/*JNIEXPORT jbyteArray JNICALL Java_java_lang_EncryptLib_decrypt
(JNIEnv * env, jobject obj, jbyteArray data, jbyteArray key) {
char* pKey = jbyteArrayToChar(env, key);
char* pData = jbyteArrayToChar(env, data); yxyDES* my_des = new yxyDES();
my_des->InitializeKey(pKey,false);
my_des->DecryptAnyLength(pData,false);
char* ret = my_des->GetPlaintextAnyLength();
int len = strlen(ret);
ret[len] = 0;
jbyteArray bytearray;
bytearray = env->NewByteArray(len);
env->SetByteArrayRegion(bytearray, 0, len, (const signed char *)ret);
return bytearray;
}*/
JNIEXPORT jbyteArray JNICALL Java_tools_EncryptLib_getkey
(JNIEnv * env, jobject obj) {
string ret = getKey();
int len = ret.size();
jbyteArray bytearray;
bytearray = env->NewByteArray(len);
env->SetByteArrayRegion(bytearray, 0, len, (const signed char *)ret.c_str());
return bytearray;
}以上是我写的jni调用的dll部分的代码,运行的时候会出现jvm直接崩溃的问题,那位大侠给看看,是不是有内存泄漏或者什么问题。yxyDES是里面的加密类,先不考虑这个类里面有问题的情况,帮我看看我写的这个接口类有没有什么问题。不知道应该发java版还是c版,先发这里,希望有高人相助。
#include <iostream>
#include "yxyDES.h"
#include <string>using namespace std; //功能:读取文件得到密钥;
string getKey() {
char fileName[] = "C:\\key.txt";
ifstream in(fileName);
string line;
getline(in, line);
return line;
}//功能:将Java的byte数组转换为C char *;
char * jbyteArrayToChar(JNIEnv * env, jbyteArray bytes)
{
char * rtn = NULL;
jsize len = env-> GetArrayLength(bytes);
printf("读取数据长度完成\r\n");
jbyte * arrayBody = env-> GetByteArrayElements(bytes,0);
if(len > 0)
{
rtn = new char[len+1];//(char *)malloc(len+1);
memcpy(rtn, arrayBody, len);
rtn[len]=0;
}
printf("拷贝数据完成\r\n");
env-> ReleaseByteArrayElements(bytes, arrayBody, 0);
printf("释放数据完成\r\n");
return rtn;
} jstring stoJstring(JNIEnv* env, const char* pat)
{
jclass strClass = env->FindClass("Ljava/lang/String;");
jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(pat));
env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
jstring encoding = env->NewStringUTF("utf-8");
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
} JNIEXPORT jstring JNICALL Java_tools_EncryptLib_encrypt
(JNIEnv * env, jobject obj, jbyteArray data, jbyteArray key) {
char* pKey = jbyteArrayToChar(env, key);
char* pData = jbyteArrayToChar(env, data);
printf("读取数据完成\r\n");
yxyDES* my_des = new yxyDES();
my_des->InitializeKey(pKey,false);
my_des->EncryptAnyLength(pData,false);
printf("加密数据完成\r\n");
jstring ret = stoJstring(env, my_des->GetCiphertextAnyLength());
printf("数据格式转换完成\r\n"); //当运行到这里的时候,有时候jvm会崩溃掉,不知道是因何原因
delete[] pKey;
pData = NULL;
delete[] pData;
pData = NULL;
delete my_des;
my_des = NULL;
printf("释放内存完成\r\n");
return ret;
}/*JNIEXPORT jbyteArray JNICALL Java_java_lang_EncryptLib_decrypt
(JNIEnv * env, jobject obj, jbyteArray data, jbyteArray key) {
char* pKey = jbyteArrayToChar(env, key);
char* pData = jbyteArrayToChar(env, data); yxyDES* my_des = new yxyDES();
my_des->InitializeKey(pKey,false);
my_des->DecryptAnyLength(pData,false);
char* ret = my_des->GetPlaintextAnyLength();
int len = strlen(ret);
ret[len] = 0;
jbyteArray bytearray;
bytearray = env->NewByteArray(len);
env->SetByteArrayRegion(bytearray, 0, len, (const signed char *)ret);
return bytearray;
}*/
JNIEXPORT jbyteArray JNICALL Java_tools_EncryptLib_getkey
(JNIEnv * env, jobject obj) {
string ret = getKey();
int len = ret.size();
jbyteArray bytearray;
bytearray = env->NewByteArray(len);
env->SetByteArrayRegion(bytearray, 0, len, (const signed char *)ret.c_str());
return bytearray;
}以上是我写的jni调用的dll部分的代码,运行的时候会出现jvm直接崩溃的问题,那位大侠给看看,是不是有内存泄漏或者什么问题。yxyDES是里面的加密类,先不考虑这个类里面有问题的情况,帮我看看我写的这个接口类有没有什么问题。不知道应该发java版还是c版,先发这里,希望有高人相助。
delete[] pKey;
pData = NULL; //pKey = NULL?
delete[] pData;
pData = NULL; 你delete了pKey但却没有把它置空,不知道是不是问题?
jclass strClass = env->FindClass("Ljava/lang/String;");
if (strClass == NULL) { goto exp;}
jmethodID ctorID = env->GetMethodID(strClass, " <init>", "([BLjava/lang/String;)V");
if (ctorID == NULL) { goto exp;}
jbyteArray bytes = env->NewByteArray(strlen(pat));
if (bytes == NULL) { goto exp;}
env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
jstring encoding = env->NewStringUTF("utf-8");
if (encoding == NULL) { goto exp;}
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
exp:
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
pData = NULL; //pKey = NULL?
delete[] pData;
pData = NULL;
pData = NULL;
delete[] pData;
pData = NULL;
delete my_des;
my_des = NULL;
pData 这个指针都设置为空了,以前的分配的内存就delete不掉了
再调用delete[] pData;肯定报错
delete[] pKey;
pData = NULL; 这里只是一个笔误,我改了delete[] pKey;
pKey= NULL;
delete[] pData;
pData = NULL;
delete my_des;
my_des = NULL;
之后再次运行jvm还是会出错。
jmethodID ctorID = env->GetMethodID(strClass, " <init>", "([BLjava/lang/String;)V");
运行到上面这句的时候得到的ctorID = null,不知道是什么原因?高人快出现吧,救救我。
是ExceptionInInitializerError还是OutOfMemoryError?或者是别的?
2.你的方法里没有删除jvm new出来的对象,GC就不会回收这些对象了。
你应在使用完他们后加上,
env->DeleteLocalRef(bytes);
env->DeleteLocalRef(encoding);这样才会被gc回收。
<init>前面多了一个空格,不知道是不是还是你的笔误
java.lang.NoSuchMethodError: <init>,这是问为啥?
jstring char2JString(JNIEnv* env, char* str){
// 定义变量
jstring rtn = 0;
jsize len = strlen(str);
jclass clsstring = (*env)->FindClass(env,"java/lang/String");
jstring strencode = (*env)->NewStringUTF(env,"GBK");
jmethodID mid = (*env)->GetMethodID(env,clsstring, "<init>", "([BLjava/lang/String;)V");
jbyteArray barr = (*env)->NewByteArray(env,len);
//new encode string default "GBK"
(*env)->SetByteArrayRegion(env,barr,0,len,(jbyte*)str); //call new String(byte[] b,String encode)
rtn = (jstring)(*env)->NewObject(env,clsstring,mid,barr,strencode);
return (rtn);
}
为什么你是运行了几次后才这样呢,比较奇怪。