c++ java相互调用
2016-04-09 15:50
399 查看
最近在接入android渠道sdk时遇到一些问题,整理一下以备后查(开发引擎是cocos2d-x):
1.c++调用java函数:通过jni来访问;
例A:
例B:
save_roleInfo是一个无返回值有形参的静态函数,形参为jstring类型,注意列表中 Ljava/lang/String; 后面带的是分号
例C:
isInWifi是一个返回boolean类型的无参函数 注意此处调用使用的是CallStaticBooleanMethod 而非CallStaticVoidMethod
返回其他类型的函数需调用相应的api
2.c++通过java调起sdk的登录支付使之在主线程运行
使用this.runOnUiThread(......) 进行切换
例:
3.ja
aeed
va调用c++(一般是登录或支付拿到sdk的token 向游戏服务器进行验证)
①新建一个java文件,定义需要使用的函数,函数声明加上native标识,表示这是一个是java调用非java函数的接口
例:这是我新建的一个wrapper.java文件
package org.cocos2dx.cpp;
public class wrapper
{
public static nativevoid nativeAnthenLogin(String token);//参数为sdk返回登录认证的token
}
②使用javah命令生成c++头文件
javah -classpath /Users/sant/Documents/Develop/Test/proj.android/src org.cocos2dx.cpp.wrapper
注意:classpath 只需要定位到src目录
生成的头文件org_cocos2dx_cpp_wrapper.h如下:
③新建一个cpp文件实现对应的函数
例
④以上三步搞定了以后 就可以在java文件中调用wrapper.nativeAnthenLogin(token)
1.c++调用java函数:通过jni来访问;
例A:
void TKSDKFunc::login() { #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) JniMethodInfo t; if (JniHelper::getStaticMethodInfo(t , "org/cocos2dx/cpp/AppActivity" , "start_login" , "()V")) { t.env->CallStaticVoidMethod(t.classID, t.methodID); t.env->DeleteLocalRef(t.classID); } # endif }start_login是一个无返回值无形参的静态函数;
例B:
void TKSDKFunc::saveRoleInfo(string roleId,string rolelevel,string roleName,string area) { #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) JniMethodInfo t; if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/cpp/AppActivity", "save_roleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V")) { jstring str0; jstring str1; jstring str2; jstring str3; str0=t.env->NewStringUTF(roleId.c_str()); str1=t.env->NewStringUTF(rolelevel.c_str()); str2=t.env->NewStringUTF(roleName.c_str()); str3=t.env->NewStringUTF(area.c_str()); t.env->CallStaticVoidMethod(t.classID, t.methodID, str0,str1,str2,str3); t.env->DeleteLocalRef(str0); t.env->DeleteLocalRef(str1); t.env->DeleteLocalRef(str2); t.env->DeleteLocalRef(str3); t.env->DeleteLocalRef(t.classID); } #endif }
save_roleInfo是一个无返回值有形参的静态函数,形参为jstring类型,注意列表中 Ljava/lang/String; 后面带的是分号
例C:
bool TKSDKFunc::isInWifi() { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) JniMethodInfo t; if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/cpp/AppActivity", "isInWifi", "()Z")) { jboolean ret = t.env->CallStaticBooleanMethod(t.classID, t.methodID); t.env->DeleteLocalRef(t.classID); return ret; } #endif }
isInWifi是一个返回boolean类型的无参函数 注意此处调用使用的是CallStaticBooleanMethod 而非CallStaticVoidMethod
返回其他类型的函数需调用相应的api
2.c++通过java调起sdk的登录支付使之在主线程运行
使用this.runOnUiThread(......) 进行切换
例:
public static void start_login(){ //将sdk登录 放到主线程中 _activity.runOnUiThread(new Runnable() { @Override public void run() { _activity.login(); //login()中调起sdk登录 } }); }
3.ja
aeed
va调用c++(一般是登录或支付拿到sdk的token 向游戏服务器进行验证)
①新建一个java文件,定义需要使用的函数,函数声明加上native标识,表示这是一个是java调用非java函数的接口
例:这是我新建的一个wrapper.java文件
package org.cocos2dx.cpp;
public class wrapper
{
public static nativevoid nativeAnthenLogin(String token);//参数为sdk返回登录认证的token
}
②使用javah命令生成c++头文件
javah -classpath /Users/sant/Documents/Develop/Test/proj.android/src org.cocos2dx.cpp.wrapper
注意:classpath 只需要定位到src目录
生成的头文件org_cocos2dx_cpp_wrapper.h如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class org_cocos2dx_cpp_wrapper */ #ifndef _Included_org_cocos2dx_cpp_wrapper #define _Included_org_cocos2dx_cpp_wrapper #ifdef __cplusplus extern "C" { #endif /* * Class: org_cocos2dx_cpp_wrapper * Method: nativeAnthenLogin * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_wrapper_nativeAnthenLogin (JNIEnv *, jclass, jstring); #ifdef __cplusplus } #endif #endif
③新建一个cpp文件实现对应的函数
例
#include <jni.h> #include "org_cocos2dx_cpp_wrapper.h" JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_wrapper_nativeAnthenLogin (JNIEnv *env, jclass, jstring jstr) { //需将jstring 转换成string char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); std::string str = rtn; CCLog("token:%s --", str.c_str()); SDK_FUNC()->requestsss(str); }
④以上三步搞定了以后 就可以在java文件中调用wrapper.nativeAnthenLogin(token)
相关文章推荐
- C/C++程序的内存分配
- C语言 数组类型与数组指针类型
- ::在C++中是什么意思
- OpenCV实践之路——人脸检测(C++/Python)
- Qt C++ 指向对象的指针与内存分配的问题分析
- CSP考试 2014年09月第3题 字符串匹配 C语言实现
- 算法复习-红黑树-c++实现
- 【C语言】单链表
- C++设计模式<五>:Observe观察者模式
- C++ STL中哈希表 hash_map介绍
- C++ 虚函数表解析
- 关于C++中子类调用父类方法的一个问题
- VC++ 访问数据库实例详解图解
- C++实验3-定期存款利息计算器
- HDU 1114 完全背包
- C语言实现选择排序、冒泡排序和快速排序的代码示例
- 33.C语言宏定义和预处理
- c/c++标准预定义宏 .
- Why? 在C++中调用被C编译后的函数,要在声明的前面加extern "C"
- 指针和引用的区别