c++ java setobjectarrayelement_关于cocos2d-x-3.11.1中c++层中调用android中的java方法

packageorg.cocos2dx.cpp;

importandroid.os.Handler;

public classJniTestHelper {

private staticHandler mHandler;

public static voidinit(Handler handler)

{

JniTestHelper.mHandler= handler;

}

public static native voidsetPackageName(String packageName);

public static intgetNumberSteps()

{

return100;

}

public staticString getPackageName()

{

return"com.andoird.org.huigao";

}

}

c++中的代码:

#include "cocos2d.h"

#include "platform/android/jni/JniHelper.h"

#include

using namespace cocos2d;

int open()

{

JniMethodInfo minfo;

bool isHave = JniHelper::getStaticMethodInfo(minfo, "org/cocos2dx/cpp/JniTestHelper", "getNumberSteps", "()I");

if (! isHave)

{

cocos2d::log("FAIL: CbCCBLECentralManager - open");

return 0;

}

int result = minfo.env->CallStaticIntMethod(minfo.classID, minfo.methodID);

return result;

}

std::string getPackageName()

{

JniMethodInfo minfo;

bool isHave = JniHelper::getStaticMethodInfo(minfo, "org/cocos2dx/cpp/JniTestHelper", "getPackageName", "()Ljava/lang/String;");

if (! isHave)

{

cocos2d::log("FAIL: CbCCBLECentralManager - open");

return "111";

}

jstring resultJ = (jstring)minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);

std::string result = JniHelper::jstring2string(resultJ);

return result;

}

需要注意的是c++中调用java中的返回类型是String的时候需要注意一下:

下面是调用java中的static方法对应的方法,如果java中的方法返回的是String类型需要调用CallStaticObjectMethod方法,然后再转成c++中的str::string 方法。

附两个链接:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp20949

http://www.waitingfy.com/archives/1648

cocos2d 中使用jni C++ 调用 Java 方法

1.简单数据类型例子

2.看一个字符串的例子,字符串会有点麻烦:

3.看一个数组例子

4.看一个自定义class的例子

1.简单数据类型例子

假设我们Java中有这么一个open的静态方法,它没有参数,有一个int的返回值。怎么在C++中调用它呢?

package cb.CbCCBLE;

public class CbCCBLECentralManager {

public static final String TAG = "CbCCBLECentralManager Android";

public static int open()

{

Log.d(TAG,"open");

return 1;

}

}

下面就是下面具体的调用方法,难点主要就是getStaticMethodInfo方法的传入参数。 注意到cb/CbCCBLE/CbCCBLECentralManager,就是安卓的具体包名加上class名字,用中间都加’/'。”open”就是方法的名字,最后一个是传入参数和输出参数,比较完全匹配才能找到这个java方法,括号内是输入参数,右边跟着返回值。

#if defined(ANDROID)

#include "platform/android/jni/JniHelper.h"

#include

int CbCCBLECentralManager::open()

{

JniMethodInfo minfo;

bool isHave = JniHelper::getStaticMethodInfo(minfo, "cb/CbCCBLE/CbCCBLECentralManager", "open", "()I");

if (! isHave)

{

CCLOG("FAIL: CbCCBLECentralManager - open");

return 0;

}

int result = minfo.env->CallStaticIntMethod(minfo.classID, minfo.methodID);

return result;

}

#endif

参数和返回值都会用特殊简写来代替,不是int,比如I代表int。完整的参数对于如下:

参数类型参数简写

boolean  Z

byte B

charC

shortS

intI

longJ

floatF

doubleD

voidV

表格中提到的简单类型如果是多个的话用比如是:

public class CbCCBLECentralManager {

public static final String TAG = "CbCCBLECentralManager Android";

public static int open(int a, int b)

{

Log.d(TAG,"open");

return 1;

}

}

C++调用就如下了:

?

1

JniHelper::getStaticMethodInfo(minfo, "cb/CbCCBLE/CbCCBLECentralManager", "open", "()II");

注意下CallStaticIntMethod,因为我们调用的是静态的返回int的方法,所以用了这个,要根据调用的方法不同而使用不同的东西,具体参考:  http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp2556

2.看一个字符串的例子,字符串会有点麻烦:

Java:

public static int scanPeripheralWithName(String name, long duration)

{

Log.d(TAG,"scanPeripheralWithName name:" + name + " duration:" + duration);

return 1;

}

C++

int CbCCBLECentralManager::scanPeripheralWithName(std::string name, long duration)

{

JniMethodInfo minfo;

bool isHave = JniHelper::getStaticMethodInfo(minfo, "cb/CbCCBLE/CbCCBLECentralManager", "scanPeripheralWithName", "(Ljava/lang/String;J)I");

if (! isHave)

{

CCLOG("FAIL: CbCCBLECentralManager - scanPeripheralWithName");

return 0;

}

jstring jname = minfo.env->NewStringUTF(name.c_str());

jlong jDuration = (long)duration;

int result = minfo.env->CallStaticIntMethod(minfo.classID, minfo.methodID,jname, jDuration);

return result;

}

string是一个jobject,jobject要加L作为前缀,因为java中的string类完整+包名就是java/lang/String.所以string的完整就是 Ljava/lang/String,因为是jobject,所以用’;'作为结束。

要注意的是CallStaticIntMethod的最后2个参数,我们传进去了一个jstring和一个jlong。什么是jstring呢?是这样的:

jni有自己的数据类型,一般是j开头,用它们作为java 和 c++的中间媒体。

JNI TypesJava Type

voidvoid

jbooleanboolean

jbytebyte

jcharchar

jshortshort

jintint

jlonglong

jfloatfloat

jdoubledouble

jobjectAll Java objects

jclassjava.lang.Class objects

jstringjava.lang.String objects

jobjectArrayArray of objects

jbooleanArrayArray of booleans

jbyteArrayArray of bytes

jshortArrayArray of shorts

jintArrayArray of integers

jlongArrayArray of longs

jfloatArrayArray of floats

jdoubleArrayArray of doubles

public static String[] getAllPeripherals()

{

Log.d(TAG,"getAllPeripherals");

String[] resultArray = {"testPeripheral1", "testPeripheral2"}; //just for test

return resultArray;

}

std::vector CbCCBLECentralManager::getAllPeripherals()

{

std::vector stdResult;

JniMethodInfo minfo;

bool isHave = JniHelper::getStaticMethodInfo(minfo, "cb/CbCCBLE/CbCCBLECentralManager", "getAllPeripherals", "()[Ljava/lang/String;");

if (! isHave)

{

CCLOG("FAIL: CbCCBLECentralManager - getAllPeripherals");

//return stdResult;

return stdResult;

}

jobjectArray jResult = static_cast(minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID));

jsize resultSize = minfo.env->GetArrayLength(jResult);

jsize index = 0;

while(index < resultSize)

{

jstring eachElement = (jstring)minfo.env->GetObjectArrayElement(jResult, index);

std::string stdString = JniHelper::jstring2string(eachElement);

stdResult.push_back(stdString);

++index;

}

return stdResult;

}

数组前面要加上一个'[', 这里还用了些其他方法,像得到数组长度,根据index得到数组内容。

传入字符串的例子:

public static int scanPeripheralWithServiceUUIDs(String[] serviceUUIDs, long duration)

{

Log.d(TAG,"scanPeripheralWithServiceUUIDs:" + duration);

}

int CbCCBLECentralManager::scanPeripheralWithServiceUUIDs(std::vectorserviceUUIDs,long duration){

JniMethodInfo minfo;

bool isHave = JniHelper::getStaticMethodInfo(minfo, "cb/CbCCBLE/CbCCBLECentralManager", "scanPeripheralWithServiceUUIDs", "([Ljava/lang/String;J)I");

if (! isHave)

{

CCLOG("FAIL: CbCCBLECentralManager - scanPeripheralWithServiceUUIDs");

return 0;

}

jint size = serviceUUIDs.size();

jclass StringObject = minfo.env->FindClass("java/lang/String");

jobjectArray jServiceUUIDsArray = minfo.env->NewObjectArray( size, StringObject, NULL);

jlong jDuration = (long)duration;

for(int i = 0; i < serviceUUIDs.size(); i++)

{

jstring serviceUUID = minfo.env->NewStringUTF(serviceUUIDs[i].c_str());

minfo.env->SetObjectArrayElement(jServiceUUIDsArray, i, serviceUUID);

}

int result = minfo.env->CallStaticIntMethod(minfo.classID, minfo.methodID, jServiceUUIDsArray, jDuration);

return result;

}

4.看一个自定义class的例子

package OurBLE;

public class OurBlePeripheralAdvertisementData

{

public String deviceName;

public String getDeviceName(){

return deviceName;

}

}

比如说有这么一个class作为jni如何传递呢?其实跟那个string类似。

public static OurBlePeripheralAdvertisementData getPeripheralAdvertisementData(String peripheralId)

{

Log.d(TAG,"getPeripheralAdvertisementData");

OurBlePeripheralAdvertisementData result = new OurBlePeripheralAdvertisementData();

result.deviceName = "deviceName1";

return result;

}

CbCCBLEPeripheralAdvertisementData CbCCBLECentralManager::getPeripheralAdvertisementData(std::string peripheralId)

{

CbCCBLEPeripheralAdvertisementData data = CbCCBLEPeripheralAdvertisementData();

JniMethodInfo minfo;

bool isHave = JniHelper::getStaticMethodInfo(minfo, "cb/CbCCBLE/CbCCBLECentralManager", "getPeripheralAdvertisementData", "(Ljava/lang/String;)LOurBLE/OurBlePeripheralAdvertisementData;");

if (! isHave)

{

CCLOG("FAIL: CbCCBLECentralManager - getPeripheralAdvertisementData");

return data;

}

jstring jPeripheralId = minfo.env->NewStringUTF(peripheralId.c_str());

jobject result = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID, jPeripheralId);

jclass CbCCBLEPeripheralAdvertisementDataClass = minfo.env->FindClass("OurBLE/OurBlePeripheralAdvertisementData");

jmethodID deviceNameMId = minfo.env->GetMethodID(CbCCBLEPeripheralAdvertisementDataClass, "getDeviceName", "()Ljava/lang/String;");

jstring jDeviceName = (jstring)minfo.env->CallObjectMethod(result, deviceNameMId);

//deviceName

data.deviceName = JniHelper::jstring2string(jDeviceName);

return data;

}

主要这里还用了些FindClass,GetMethodID, CallObjectMethod API,这样class就能传递了。

jni真的是无所不能啊。java调用c++参考这篇文章。 《cocos2d 中使用jni Java 调用 C++ 方法》http://www.waitingfy.com/archives/1648

CallStaticVoidMethod()

CallStaticVoidMethodA()

CallStaticVoidMethodV()

void

CallStaticObjectMethod()

CallStaticObjectMethodA()

CallStaticObjectMethodV()

jobject

CallStaticBooleanMethod()

CallStaticBooleanMethodA()

CallStaticBooleanMethodV()

jboolean

CallStaticByteMethod()

CallStaticByteMethodA()

CallStaticByteMethodV()

jbyte

CallStaticCharMethod()

CallStaticCharMethodA()

CallStaticCharMethodV()

jchar

CallStaticShortMethod()

CallStaticShortMethodA()

CallStaticShortMethodV()

jshort

CallStaticIntMethod()

CallStaticIntMethodA()

CallStaticIntMethodV()

jint

CallStaticLongMethod()

CallStaticLongMethodA()

CallStaticLongMethodV()

jlong

CallStaticFloatMethod()

CallStaticFloatMethodA()

CallStaticFloatMethodV()

jfloat

CallStaticDoubleMethod()

CallStaticDoubleMethodA()

CallStaticDoubleMethodV()

jdouble

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值