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
- Android App中通过JNI调用C/C++代码(二)
- Android App中通过JNI调用C/C++代码
- android中如何通过jni调用c,c++代码
- 通过JNI接口在Android中调用C/C++代码
- android 通过JNI调用C/C++代码(linux)
- android实现app通过jni调用C/C++方法
- android实现app通过jni调用C/C++方法
- android通过jni调用C代码socket出错问题
- android通过jni调用C代码socket出错问题
- Android Studio中通过jni实现对C/C++代码的调用,HelloJni,Ubuntu
- JNI(二)、 Java 代码调用 C代码
- Android C 通过JNI 调用JAVA
- Android中JNI(二)------java调用C和C回调java
- Android JNI简单实例(android 调用C/C++代码)
- Android JNI简单实例(android 调用C/C++代码)
- Android JNI简单实例(android 调用C/C++代码)
- Android JNI简单实例(android 调用C/C++代码)
- 用Android Studio通过Java代码调用C代码的JNI流程
- Java对空格的encode格式问题
- 最短路径(需要使用高精度整数)
- 卷积神经网络CNN经典模型整理Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning,squeezenet
- HDU-2588-GCD
- 类的初始化操作
- Android App中通过JNI调用C/C++代码(二)
- spring使用aop时需要设置proxy-target-class="true" 否则无法依赖注入
- 最新版本sublime text3注册码
- FragmentTransaction切换问题
- NLPIR/ICTCLAS 2015 分词系统使用
- 怎么用图片取代radio的图标且图片能随着点击而变换
- Manthan, Codefest 17 Marvolo Gaunt's Ring
- LeetCode
- 新的Java 9功能一目了然