您的位置:首页 > 移动开发 > Cocos引擎

cocos2dx jni交互 获取java函数返回的字符串

2017-01-17 12:41 751 查看
1:C++调用java的无返回值函数。

(1):首先在C++端声明如下函数: (此函数由C++端调用,然后在该函数中,调用java端代码)

//@param apkName  下载好之后,命名的apkName
static void writeToSDCard(const char* apkName,const char* apkContent);

(2):C++端实现函数

"(Ljava/lang/String;Ljava/lang/String
4000
;)V"为签名,代码2个string参数,无返回值


public static void writeApkToFile(String apkName,String fileInfo);

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)//头文件包含
#include <jni.h>
#include <android/log.h>
#include "platform/android/jni/JniHelper.h"

#define  CLASS_NAME "org/cocos2dx/cpp/OperateSDCard" //java端方法所在的类
#endif

//public static void writeApkToFile(String apkName,String fileInfo){
void WriteApkToSDCard::writeToSDCard(const char* apkName, const char* apkContent)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo t;
//把流内容写入文件
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "writeApkToFile", "(Ljava/lang/String;Ljava/lang/String;)V"))
{
jstring jApkName = t.env->NewStringUTF(apkName);
jstring jApkContent = t.env->NewStringUTF(apkContent);
t.env->CallStaticVoidMethod(t.classID, t.methodID, jApkName,jApkContent);
t.env->DeleteLocalRef(jApkName);
t.env->DeleteLocalRef(jApkContent);
}
#endif
}
CallStaticVoidMethod代表调用java端,无返回值方法。

(3):Java端方法(Java端的类放在src/org/cocos2dx/cpp下面)

public static void writeApkToFile(String apkName,String fileInfo){
try {
File file = new File(Environment.getExternalStorageDirectory(),apkName);  //"123.txt"
BufferedWriter bw = new BufferedWriter(new FileWriter(file, false));
String info = fileInfo;//"dear123";  //fileInfo
bw.write(info);
bw.flush();
System.out.println("写入完成");
} catch (Exception e) {
e.printStackTrace();
}
}


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2:C++调用java的返回值字符串的函数。

(1):首先在C++端声明如下函数: (此函数由C++端调用,然后在该函数中,调用java端代码)

//获取sdcard的路径
static std::string getSDCardPath();


(2):C++端实现函数

/*
参考链接  http://www.cocoachina.com/bbs/read.php?tid=234998 http://www.cnblogs.com/benxintuzi/p/4593137.html http://blog.csdn.net/lognic10/article/details/22828589 http://www.2cto.com/kf/201402/279085.html

sdpath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/";
*/
std::string WriteApkToSDCard::getSDCardPath()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getSdCardPath", "()Ljava/lang/String;"))
{
//获取java返回的字符串
jstring jstr = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
const char* str= t.env->GetStringUTFChars(jstr, NULL);

std::string ret(str);//把字符串拷贝一份,然后释放掉原字符串,防止内存泄露

t.env->ReleaseStringUTFChars(jstr, str);//str
t.env->DeleteLocalRef(jstr);//释放jstr
return ret;

//jstring js_pkn = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
//std::string str_pkn = JniHelper::jstring2string(js_pkn);  
//t.env->Delete(str_pkn);
//return str_pkn;
}
#endif
}


CallStaticObjectMethod 调用java有返回值的方法

jstring转化为std::string

jstring jstr = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
const char* str= t.env->GetStringUTFChars(jstr, NULL);
t.env->ReleaseStringUTFChars(jstr, str);
t.env->DeleteLocalRef(jstr);


(3):Java端方法

/**
*获取sd卡路径
*
* @return
*/
public static String getSdCardPath() {
/*		String sdpath = "/storage/sdcard0/";
return sdpath;*/

boolean exist = isSdCardExist();
String sdpath = "";
if (exist) {
////sdpath = Environment.getExternalStorageDirectory().getPath() + "/";
sdpath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/";
Log.e("OperateSDCard.getSDcardPath normal", sdpath);
} else {
sdpath = "sdcard不存在";
Log.e("OperateSDCard.getSDcardPath error", sdpath);
}
return sdpath;
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3:C++传递给java字符串,并且调用java的返回值字符串的函数。侧重内存释放

(1):首先在C++端声明如下函数: (此函数由C++端调用,然后在该函数中,调用java端代码)

#pragma once
#ifndef __AESUtils_H_
#define __AESUtils_H_

#include <stdio.h>
#include "cocos2d.h"

USING_NS_CC;

/*
加密

date : 2017.01.20
author :
*/

class AESUtils
{
public:
//加密
static const char* encrypt(const char* sSrc);

//解密
static const char* decrypt(const char* sSrc);

};
#endif //__AESUtils_
#include "AESUtils.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include <android/log.h>
#include "platform/android/jni/JniHelper.h"

#define  CLASS_NAME "org/cocos2dx/cpp/AESUtil"
#endif
std::string AESUtils::encrypt(const char* sSrc)
{#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)JniMethodInfo t;if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "encrypt", "(Ljava/lang/String;)Ljava/lang/String;")){jstring jsSrc = t.env->NewStringUTF(sSrc);//获取java返回的字符串jstring
jstr = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID,jsSrc);const char* str = t.env->GetStringUTFChars(jstr, NULL);std::string ret(str);//拷贝一份字符串,然后释放strt.env->ReleaseStringUTFChars(jstr, str);//释放strt.env->DeleteLocalRef(jsSrc);//释放jsSrct.env->DeleteLocalRef(jstr);//释放jstrreturn
ret;//jstring js_pkn = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);//std::string str_pkn = JniHelper::jstring2string(js_pkn); //t.env->Delete(str_pkn);//return str_pkn;}#else if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32return "win32 client
encrypt";#endif}
std::string AESUtils::decrypt(const char* sSrc)
{#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)JniMethodInfo t;if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "decrypt", "(Ljava/lang/String;)Ljava/lang/String;")){jstring jsSrc = t.env->NewStringUTF(sSrc);//获取java返回的字符串jstring
jstr = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID,jsSrc);const char* str = t.env->GetStringUTFChars(jstr, NULL);std::string ret(str);t.env->DeleteLocalRef(jsSrc);t.env->ReleaseStringUTFChars(jstr, str);t.env->DeleteLocalRef(jstr);return ret;}#else
if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32return "win32 client decrypt";#endif}


(2):Java端方法(Java端的类放在src/org/cocos2dx/cpp下面)
public static String encrypt(String sSrc) {
return "";
}


经测试,发现jni中,字符串需要自己手动释放。

1:自己从c++传给java的字符串

2:java返回的字符串

3:java返回之后转化为c的字符串
http://blog.csdn.net/tianxiawuzhei/article/details/44569061 http://blog.csdn.net/liuzhimayi/article/details/51504870
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐