cocos2dx3.X中C++与lua互调

本文介绍了一种使用C++和Lua进行跨语言调用的方法,通过创建自定义类`HclcData`,实现了从C++到Lua的函数调用以及从Lua到C++的数据传递。详细展示了如何在Lua中调用C++方法并获取返回值,以及如何从Lua文件中获取C++变量和表数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//
//  HclcData.h
//  CppLua
//
//  Created by Himi on 13-4-17.
//
//

#ifndef __CppLua__HclcData__
#define __CppLua__HclcData__

#include "cocos2d.h"
using namespace cocos2d;
using namespace std;

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};

struct returnTableStruct
{
	string f;
	string s;
};

class HclcData{
public:
    static HclcData* sharedHD();
    
    //------------  c++ -> lua ------------//
    
    /*
     getLuaVarString : 调用lua全局string
     
     luaFileName  = lua文件名
     varName = 所要取Lua中的变量名
     */
    const char* getLuaVarString(const char* luaFileName,const char* varName);
    
    /*
     getLuaVarOneOfTable : 调用lua全局table中的一个元素
     
     luaFileName  = lua文件名
     varName = 所要取Lua中的table变量名
     keyName = 所要取Lua中的table中某一个元素的Key
     */
    const char* getLuaVarOneOfTable(const char* luaFileName,const char* varName,const char* keyName);
    
    /*
     getLuaVarTable : 调用lua全局table
     
     luaFileName  = lua文件名
     varName = 所要取的table变量名
     
     (注:返回的是所有的数据,童鞋们可以自己使用Map等处理)
     */
   std::vector<returnTableStruct> getLuaVarTable(const char* luaFileName,const char* varName);
    
    /*
     callLuaFunction : 调用lua函数
     
     luaFileName  = lua文件名
     functionName = 所要调用Lua中的的函数名
     */
    const char* callLuaFunction(const char* luaFileName,const char* functionName);
	带参执行Lua方法有返回值
	//const char* callLuaFuncParReturn(const char* luaFileName,const char* functionName,std::vector<String>* arraypar,std::vector<String>* arraypartype);
	带参执行Lua方法无返回值
	//const void callLuaFuncPar(const char* luaFileName,const char* functionName,std::vector<String>* arraypar,std::vector<String>* arraypartype);
    
    //------------  lua -> c++ ------------//
    
    void callCppFunction(const char* luaFileName);
    
private:
    static int cppFunction(lua_State* ls);
    
    static bool _isFirst;
    static HclcData* _shared;
    const char* getFileFullPath(const char* fileName);
    ~HclcData();
};

#endif /* defined(__CppLua__HclcData__) */
//
//  HclcData.cpp
//  CppLua
//
//  Created by Himi on 13-4-17.
//
//

#include "HclcData.h"
#include "CCLuaEngine.h"
#include "cocos2d.h"
#include <map>
#include <string> 
#include <iostream> 


bool HclcData::_isFirst;
HclcData* HclcData::_shared;

HclcData* HclcData::sharedHD(){
	if(!_isFirst){
		_shared = new HclcData();
	}
	return _shared;
}

const char* HclcData::getLuaVarString(const char* luaFileName,const char* varName){

	lua_State*  ls = LuaEngine::getInstance()->getLuaStack()->getLuaState();

	/*int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName));
	if(isOpen!=0){
	CCLOG("Open Lua Error: %i", isOpen);
	return NULL;
	}*/

	lua_settop(ls, 0);
	lua_getglobal(ls, varName);

	int statesCode = lua_isstring(ls, 1);
	if(statesCode!=1){
		CCLOG("Open Lua Error: %i", statesCode);
		return NULL;
	}

	const char* str = lua_tostring(ls, 1);
	lua_pop(ls, 1);

	return str;
}

const char* HclcData::getLuaVarOneOfTable(const char* luaFileName,const char* varName,const char* keyName){

	lua_State*  ls = LuaEngine::getInstance()->getLuaStack()->getLuaState();

	/* int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName));
	if(isOpen!=0){
	CCLOG("Open Lua Error: %i", isOpen);
	return NULL;
	}*/

	lua_getglobal(ls, varName);

	int statesCode = lua_istable(ls, -1);
	if(statesCode!=1){
		CCLOG("Open Lua Error: %i", statesCode);
		return NULL;
	}

	lua_pushstring(ls, keyName);
	lua_gettable(ls, -2);
	const char* valueString = lua_tostring(ls, -1);

	lua_pop(ls, -1);

	return valueString;
}

std::vector<returnTableStruct> HclcData::getLuaVarTable(const char* luaFileName,const char* varName){

	lua_State*  ls = LuaEngine::getInstance()->getLuaStack()->getLuaState();

	/*int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName));
	if(isOpen!=0){
	CCLOG("Open Lua Error: %i", isOpen);
	return NULL;
	}*/

	lua_getglobal(ls, varName);

	int it = lua_gettop(ls);
	lua_pushnil(ls);

	string result="";
	std::vector<returnTableStruct> vmap;

	while(lua_next(ls, it))
	{
		string key = lua_tostring(ls, -2);
		string value = lua_tostring(ls, -1);

		result=result+key+":"+value+"\t";
		returnTableStruct temp;
		temp.f=key;
		temp.s=value;
		vmap.push_back(temp);


		lua_pop(ls, 1);
	}
	lua_pop(ls, 1);

	return vmap;
}

const char* HclcData::callLuaFunction(const char* luaFileName,const char* functionName){
	lua_State*  ls = LuaEngine::getInstance()->getLuaStack()->getLuaState();

	/*int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName));
	if(isOpen!=0){
	CCLOG("Open Lua Error: %i", isOpen);
	return NULL;
	}*/

	lua_getglobal(ls, functionName);

	lua_pushstring(ls, "bbjxl");
	lua_pushnumber(ls, 23);
	lua_pushboolean(ls, true);
	

	/*
	lua_call
	第一个参数:函数的参数个数
	第二个参数:函数返回值个数
	*/
	lua_call(ls, 3, 1);

	const char* iResult = lua_tostring(ls, -1);

	return iResult;
}

//带参执行Lua方法有返回值
//const char* HclcData::callLuaFuncParReturn(const char* luaFileName,const char* functionName,std::vector<String>* arraypar,std::vector<String>* arraypartype){
//    lua_State*  ls = LuaEngine::getInstance()->getLuaStack()->getLuaState();
//    
//   
//    
//    lua_getglobal(ls, functionName);
//	int countnum = arraypar->size();
//    if(countnum>0)
//    {
//        for (int i = 0; i<arraypar->size(); i++) {
//            String* typestr = (String*)arraypartype[i];
//            String* strnr = (String*)arraypar[i];
//            if(typestr->isEqual(String::create("string")))
//            {
//                lua_pushstring(ls, strnr->getCString());
//            }
//            else if(typestr->isEqual(String::create("int")))
//            {
//                lua_pushnumber(ls, strnr->intValue());
//            }
//            else if(typestr->isEqual(String::create("bool")))
//            {
//                lua_pushboolean(ls, strnr->boolValue());
//            }
//        }
//    }
//    /*
//     lua_call
//     第一个参数:函数的参数个数
//     第二个参数:函数返回值个数
//     */
//    lua_call(ls, countnum, 1);
//    
//    const char* iResult = lua_tostring(ls, -1);
//    
//    return iResult;
//}

//带参执行Lua方法无返回值
//const void HclcData::callLuaFuncPar(const char* luaFileName,const char* functionName,CCArray* arraypar,CCArray* arraypartype){
//    lua_State*  ls = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState();
//    
//    int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName));
//    if(isOpen!=0){
//        CCLOG("Open Lua Error: %i", isOpen);
//    }
//    
//    lua_getglobal(ls, functionName);
//    int countnum = arraypar->count();
//    if(countnum>0)
//    {
//        for (int i = 0; i<arraypar->count(); i++) {
//            CCString* typestr = (CCString*)arraypartype->objectAtIndex(i);
//            CCString* strnr = (CCString*)arraypar->objectAtIndex(i);
//            if(typestr->isEqual(CCString::create("string")))
//            {
//                lua_pushstring(ls, strnr->getCString());
//            }
//            else if(typestr->isEqual(CCString::create("int")))
//            {
//                lua_pushnumber(ls, strnr->intValue());
//            }
//            else if(typestr->isEqual(CCString::create("bool")))
//            {
//                lua_pushboolean(ls, strnr->boolValue());
//            }
//        }
//    }
//    /*
//     lua_call
//     第一个参数:函数的参数个数
//     第二个参数:函数返回值个数
//     */
//    lua_call(ls, countnum, 0);
// 
//}


void  HclcData::callCppFunction(const char* luaFileName){

	lua_State*  ls = LuaEngine::getInstance()->getLuaStack()->getLuaState();

	/*
	Lua调用的C++的函数必须是静态的
	*/
	lua_register(ls, "cppFunction", cppFunction);

	int isOpen = luaL_dofile(ls, getFileFullPath(luaFileName));
	if(isOpen!=0){
		CCLOG("Open Lua Error: %i", isOpen);
		return;
	}
}

int HclcData::cppFunction(lua_State* ls){
	int luaNum = (int)lua_tonumber(ls, 1);
	int luaStr = (int)lua_tostring(ls, 2);
	CCLOG("Lua调用cpp函数时传来的两个参数: %i  %s",luaNum,luaStr);

	/*
	返给Lua的值
	*/
	lua_pushnumber(ls, 321);
	lua_pushstring(ls, "Himi");

	/*
	返给Lua值个数
	*/
	return 2;
}

const char* HclcData::getFileFullPath(const char* fileName){
	return FileUtils::getInstance()->fullPathForFilename(fileName).c_str();
}

HclcData::~HclcData(){

	CC_SAFE_DELETE(_shared);
	_shared=NULL;
}

调用:

auto engine = LuaEngine::getInstance();

	
	HclcData::sharedHD()->callCppFunction("src/Test.lua");//注册CPP方法,lua中直接调用cpp方法,详见LUA文件

    ScriptEngineManager::getInstance()->setScriptEngine(engine);
    if (engine->executeScriptFile("src/Test.lua")) {
        return false;
    }
	const char* iResults=HclcData::sharedHD()->callLuaFunction("Test.lua","luaLogString");
	//cout<<iResults<<endl;
	const char* getTabe=HclcData::sharedHD()->getLuaVarOneOfTable("Test.lua","luaTable","name");//lua文件名,表名,key
	//log("%s",getTabe);

	const char* getVar=HclcData::sharedHD()->getLuaVarString("Test.lua","luaStr2");//lua文件名,变量名
	log("%s",getVar);

	vector < returnTableStruct > result=HclcData::sharedHD()->getLuaVarTable("Test.lua","luaTable");

lua:

luaStr  = "I' m Himi"
 
luaStr2 = "are you ok!"
 
luaTable={age = 23,name="Himi",sex="男"}
 
function luaLogString(_logStr,_logNum,_logBool)
 
    print("Lua 脚本打印从C传来的字符串:",_logStr,_logNum,_logBool)
    return "call lua function OK"
end
 
function call_Cpp(_logStr,_logNum,_logBool)
    num,str = cppFunction(999,"I'm a lua string")
    print("从cpp函数中获得两个返回值:",num,str)
end

print("lua test success")

num,str = cppFunction(999,"I'm a lua string")
print("从cpp函数中获得两个返回值:",num,str)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值