Android App中通过JNI调用C/C++代码(二)

来源:互联网 发布:济南java培训机构 编辑:程序博客网 时间:2024/06/15 17:05


前面已经实现了Android App通过JNI调用C/C++代码,但那是在一个新创建的android工程里的,如果是在cocos2dx生成的项目呢,相信是差不多的原理。

修改Android.mk文件

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := cocos2dlua_sharedLOCAL_MODULE_FILENAME := libcocos2dluaLOCAL_SRC_FILES := \../../Classes/AppDelegate.cpp \hellolua/main.cpp \../../../cocos2d-x/cocos/scripting/lua-bindings/auto/lua_cocos2dx_hello_auto.cpp \jnispace/helloJni.cppLOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \jnispaceLOCAL_STATIC_LIBRARIES := cocos2d_lua_staticinclude $(BUILD_SHARED_LIBRARY)$(call import-module,scripting/lua-bindings/proj.android)



重新打android包就可以啦,cocos compile -p android, 编译好的jni代码加入到了libcocos2dlua.so库中


虽然把JNI代码引入到了cocos2dx库里,但JNI的C代码怎么调用Cocos的逻辑代码呢?

又倒鼓了一天,终于实现了这一功能:Android Activity中调用 C方法,C方法再调用Cocos部分代码,最后进入到了Lua。


首先来看Cocos2dx C++怎么调用Lua

(一)在网上找了很多资料,还是这篇文章比较靠谱:摘自cocos2dx之C++调用Lua

LuaStack * L =LuaEngine::getInstance()->getLuaStack();      lua_State* tolua_s = L->getLuaState();            //--------有参数和返回值的Lua函数的调用---------      lua_getglobal(tolua_s, "testadd");    // 获取函数,压入栈中      lua_pushnumber(tolua_s, 10);          // 压入第一个参数      lua_pushnumber(tolua_s, 20);          // 压入第二个参数      lua_pushstring(tolua_s, "测试");       // 压入第三个参数      int iRet= lua_pcall(tolua_s, 3, 2, 0);// 调用函数,调用完成以后,会将返回值压入栈中,2表示参数个数,1表示返回结果个数。      if (iRet)                       // 调用出错      {          const char *pErrorMsg = lua_tostring(tolua_s, -1);          CCLOG("错误-------%s",pErrorMsg);          return ;      }      int fValue = lua_tonumber(tolua_s, -2);     //获取第一个返回值      string str = lua_tostring(tolua_s, -1);     //获取第二个返回值      CCLOG("有参数和返回值的Lua函数的调用---%d---,%s",fValue,str.c_str());            //--------------读取Lua的变量------------      lua_getglobal(tolua_s, "strTemp");      string strTemp = lua_tostring(tolua_s, -1);       CCLOG("读取Lua的变量---%s",strTemp.c_str());            //-------------读取Lua的table-----------      lua_getglobal(tolua_s,"tableTemp");      lua_getfield(tolua_s,-1,"name");      string strName = lua_tostring(tolua_s,-1);      CCLOG("读取Lua的table--%s",strName.c_str());  

(二)再搜出了lua_pcall的用法,摘自lua_pcall用法

lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)  


nargs:参数个数,nresults:返回值个数,errFunc:错误处理函数,0表示无,表示错误处理函数在栈中的索引


假如脚本为:


--test.lua  function test(x,y)  return x+y  end  luaL_loadfile(L, "test.lua");  



然后先压x,y的值入栈


lua_pushnumber(L,10);  lua_pushnumber(L,20);  lua_pcall(L,2,1,0);  


如果没有错误则此时栈顶的值为30.


如果运行时出错,lua_pcall会返回一个非零的结果,如果指定了错误处理函数会先调用错误处理函数,然后在将错误信息入栈,在将返回结果或者错误信息入栈之前会先将函数和参数从栈中移除。错误处理函数必须要在被调用函数和其参数入栈之前入栈。

lua_getfield(L, idx, "x")  从指定idx的表中取出指定元素x的值 并将其入栈
lua_setfield(L, idx, "x") 将栈顶的值赋给指定索引idx中的x,并pop栈顶


(三)编写自己的Lua全局方法,以待C++调用

main.lua

--全局方法,还不能写成 function globalFuncs(){}这样--此方法用作C++ 中调用Lua的示例cc.exports.globalFuncs = function(num)print(string.format("Lua print: %d", num))end

(四)C++调用Lua




工程里新建这两个文件

JNICall.h

#ifndef __JNI_CALL__#define __JNI_CALL__#include "cocos2d.h"void callFuns1(int num);#endif

JNICall.cpp

#include "JNICall.h"#include "scripting/lua-bindings/manual/CCLuaEngine.h"USING_NS_CC;using namespace std;void callFuns1(int num){auto L = LuaEngine::getInstance()->getLuaStack();    lua_State* tolua_s = L->getLuaState();    lua_getglobal(tolua_s, "globalFuncs");    lua_pushnumber(tolua_s, 30);    int ret = lua_pcall(tolua_s, 1, 0, 0);    if(ret){    // !=0表示有错误    const char* pErrorMsg = lua_tostring(tolua_s, -1);    CCLOG("error---------------------%s", pErrorMsg);    return;    }    }

JNI代码调用callFuns1方法


(五) 编译运行

修改Android.mk文件,添加JNICall.cpp


cocos compile -p android,编译成功


如果在Activity中直接调用JNI代码,这时lua引擎还没有准备好,会报错,那就做一个延时调用处理:

        new Thread(){        public void run(){        Log.d("aaaa", "jni output waiting: ");        try {Thread.sleep(5000);} catch (InterruptedException e) {}        Log.d("aaaa", "jni output: " + HelloJni.getName("a"));        }        }.start();

运行:

java中的输出


lua输出:






阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 轨道灯的轨道不够长怎么办 奔驰大灯不亮了怎么办 led顶灯不亮了怎么办 吸顶灯led灯坏了怎么办 车底盘塑料被刮怎么办 汽车门电机坏了怎么办 宁波北仑普高差三分该怎么办 上班的地方甲醛味很重怎么办 公司不给员工交社保怎么办 户口转到学校毕业了怎么办 外地户口转到北京档案怎么办 隧道防水板过紧怎么办 到国企没报到证怎么办 车子锁了油箱盖能开怎么办 单位不接受档案和户口怎么办 完税凭证弄丢了怎么办 育种玉米公本早了怎么办 网银转账打错了怎么办 转账名字打错了怎么办 普通转账名字打错了怎么办 银行账号转错了怎么办 打款信息错了怎么办 报到证过期了档案怎么办 日本suica卡丢了怎么办 日本地铁卡丢了怎么办 极光卡五星老输怎么办 皮秒留下的色沉怎么办 鼻综合鼻内增生怎么办 做完鼻综合脸肿怎么办 上海车子卖了etc怎么办 车卖了etc设备怎么办 车卖了etc没摘怎么办 交通信息卡丢了怎么办 多囊卵巢无排卵怎么办 卵巢腹镜手术后一直出汗怎么办 双侧卵巢多囊怎么办 备孕子宫内膜厚怎么办 有成熟卵泡不破怎么办 卵泡不排萎缩了怎么办 卵泡8mm一直不长怎么办 卵泡已经长到28x19mm怎么办