国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

# Lua與C++交互(二)———— 交互

這篇具有很好參考價(jià)值的文章主要介紹了# Lua與C++交互(二)———— 交互。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

C++ 調(diào)用lua

基礎(chǔ)調(diào)用

再來(lái)溫習(xí)一下
myName = “beauty girl”

# Lua與C++交互(二)———— 交互,cocos2dx學(xué)習(xí)之路,lua,交互,cocos2d

  1. C++想要獲取myName的值,根據(jù)規(guī)則,它需要把myName壓入棧中,這樣lua就能看到;
  2. lua從堆棧中獲取myName的值,此時(shí)棧頂為空;
  3. lua拿著myName去全局表中查找與之對(duì)應(yīng)的字符串;
  4. 全局表找到,并返回"beauty girl";
  5. lua把"beauty girl"壓入棧中;
  6. C++從棧中獲取"beauty girl"

用代碼來(lái)實(shí)現(xiàn)

    //創(chuàng)建一個(gè)state
    lua_State *L = luaL_newstate();
    // 重置棧頂索引 為了確認(rèn)讓棧頂?shù)乃饕脼? 置0之后,我們?nèi)霔5牡谝粋€(gè)元素的索引就是1
    lua_settop(L, 0);
    // 把myName放入棧中,然后lua去全局表中查找,找到對(duì)應(yīng)的字段,再放回棧中
    lua_getglobal(L, "myName");
    // 判斷棧頂?shù)闹档念?lèi)型是否為String, 返回非0值代表成功
    int isstr = lua_isstring(L, 1);
    
    //獲取棧頂?shù)闹?/span>
    const char* str = lua_tostring(L, 1);
    lua_close(L);

C++獲取Lua的table

helloTable = {name = “xxx”, sex = “man”}

和上面一樣,要獲取就先把helloTable放到棧頂,讓Lua知道C++要獲取這個(gè)值

    //創(chuàng)建一個(gè)state
    lua_State *L = luaL_newstate();
    // 重置棧頂索引 為了確認(rèn)讓棧頂?shù)乃饕脼? 置0之后,我們?nèi)霔5牡谝粋€(gè)元素的索引就是1
    lua_settop(L, 0);
    //獲取helloTable的值 這個(gè)時(shí)候棧底 是 helloTable
    lua_getglobal(L, "helloTable");
    
    //我們想要獲取table中name的值,那么就把name壓入棧
    //這個(gè)時(shí)候棧中是 name,helloTable,其中name是棧頂
    lua_pushstring(L, "name");
    
    //lua api提供了一個(gè)獲取table的函數(shù) lua_gettable
    //該函數(shù)會(huì)從棧頂取得一個(gè)值,然后根據(jù)這個(gè)值去table中尋找對(duì)應(yīng)的值,最后把找到的值放到棧頂 第二個(gè)參數(shù)是指table變量所在棧中的位置
    lua_gettable(L, -2); // -1永遠(yuǎn)是棧頂,那么helloTable就是-2,這里也可以用1
    
    //lua_gettable 會(huì)把值放到 棧頂 
    const char* sName = lua_tostring(pL, -1);

C++調(diào)用Lua函數(shù)

function helloAdd(num1, num2)
	return (num1 + num2)
end

這里有個(gè)新的函數(shù) lua_call

第一個(gè)參數(shù)表示函數(shù)的參數(shù)個(gè)數(shù),第二個(gè)參數(shù)表示函數(shù)返回值個(gè)數(shù)

Lua會(huì)先去堆棧取出參數(shù),然后再取出函數(shù)對(duì)象,開(kāi)始執(zhí)行函數(shù)

    //創(chuàng)建一個(gè)state
    lua_State *L = luaL_newstate();
    // 重置棧頂索引 為了確認(rèn)讓棧頂?shù)乃饕脼? 置0之后,我們?nèi)霔5牡谝粋€(gè)元素的索引就是1
    lua_settop(L, 0);
    //把helloAdd函數(shù)對(duì)象放到棧中
    lua_getglobal(L, "helloAdd");
    
    //把函數(shù)所需要的參數(shù)入棧 
    lua_pushnumber(L, 10);
    lua_pushnumber(L, 5);
    
    //調(diào)用lua_call
    lua_call(L, 2, 1);
    int iResult = lua_tonumber(L, -1);

C++調(diào)用Lua table的函數(shù)

lua中table有兩種函數(shù)

mytable={}
function mytable.StaticFunc()
    print("mytable.StaticFunc called.")
end
function mytable:Func()
    print("mytable:Func self:", self)
end

其中StaticFunc可以理解成table的靜態(tài)函數(shù),F(xiàn)unc為table的成員函數(shù)

 // 調(diào)用mytable表的靜態(tài)函數(shù)
lua_getglobal(L, "mytable"); // 將名為mytable的全局table變量的值壓棧
lua_pushstring(L, "StaticFunc"); // 將函數(shù)名為StaticFunc壓棧
lua_gettable(L, -2); // 從索引為-2處的表中,讀取key(在棧頂處)為StaticFunc的函數(shù)名  讀取成功后,將key出棧,并將讀取到的函數(shù)名入棧
lua_call(L, 0, 0); // 執(zhí)行完后將StaticFunc彈出棧  注: 第一個(gè)0表示參數(shù)個(gè)數(shù)為0,第二個(gè)0表示無(wú)返回值
    
// 調(diào)用mytable表的成員函數(shù)  采用新方法獲取函數(shù)名
lua_getfield(L, -1, "Func");// 從索引為-1處的表中,讀取key為Func的函數(shù)名  成功后將讀取到的函數(shù)名入棧
lua_pushvalue(L, -2); // 將索引為-2處的表復(fù)制一份并壓入棧頂
lua_call(L, 1, 0); // 執(zhí)行完后將Func彈出棧  注: 1表示參數(shù)個(gè)數(shù),即self指針,為當(dāng)前table,第二個(gè)0表示無(wú)返回值

唯一不同的是lua_call的時(shí)候,需要注意第二個(gè)的值,成員函數(shù)默認(rèn)需要傳遞self。

這里獲取的時(shí)候,用到了函數(shù)lua_getfield

函數(shù)原型如下

void lua_getfield (lua_State *L, int index, const char *k);

Pushes onto the stack the value t[k], where t is the value at the given valid index. As in Lua, this function may trigger a metamethod for the “index” event

大概意思,將t[k]壓入堆棧,t由參數(shù)index指定在棧中的位置

Lua 調(diào)用C++

Lua調(diào)用C++ 函數(shù)

大概的步驟如下:

  1. 將C++的函數(shù)包裝成Lua環(huán)境認(rèn)可的Lua_CFunction格式
  2. 將包裝好的函數(shù)注冊(cè)到Lua環(huán)境中
  3. 像使用普通Lua函數(shù)那樣使用注冊(cè)函數(shù)

簡(jiǎn)單的C++函數(shù)

int add(int a,int b)
{
    return a+b;
}

包裝C++函數(shù)

int add(lua_state *L)
{
    int a = lua_tonumber(-1);
    int b = lua_tonumber(-2);
    int sum = a+b;
    // 將返回值壓入棧中
    lua_pushnumber(L,sum);
    // 返回返回值個(gè)數(shù)
    return 1;
}
  1. Lua腳本里會(huì)調(diào)用add(lua_state *L)
  2. 調(diào)用add(lua_state *L)函數(shù)的時(shí)候,會(huì)反過(guò)來(lái)進(jìn)行之前的C++調(diào)用lua
  3. Lua調(diào)用add(lua_state *L)函數(shù)之后,有一個(gè)返回值,需要壓入棧中
  4. 最后return表示有多少個(gè)返回值,Lua支持多個(gè)返回值

最關(guān)鍵的一步,需要注冊(cè)C++的函數(shù),Lua才能調(diào)用

lua_register(L, "add", add);

Lua調(diào)用C++類(lèi)

這里有兩種方式,一個(gè)是用luaL_newlib方式

luaL_newlib方式

大概步驟如下:

  1. 新建創(chuàng)建對(duì)象函數(shù),調(diào)用lua_newuserdata,創(chuàng)建一個(gè)對(duì)象指針,指向new出來(lái)的新的對(duì)象。
  2. 新建成員方法,調(diào)用lua_touserdata,得到從lua中傳入的對(duì)象指針,調(diào)用成員方法。
  3. 調(diào)用luaL_newlib,將需要封裝的C++函數(shù)放入到一個(gè)lua表中壓入棧里。
  4. 將自定義模塊,注冊(cè)到Lua環(huán)境中。
  5. 在lua中,會(huì)首先調(diào)用創(chuàng)建對(duì)象函數(shù),獲得Student對(duì)象指針。通過(guò)Student對(duì)象指針,調(diào)用成員方法

Student.h

#pragma once
 
#include <iostream>
#include <string>
using namespace std;
 
class Student
{
public:
	//構(gòu)造/析構(gòu)函數(shù)
	Student();
	~Student();
 
	//get/set函數(shù)
	string get_name();
	void set_name(string name);
	unsigned get_age();
	void set_age(unsigned age);
 
	//打印函數(shù)
	void print();
 
private:
	string _name;
	unsigned _age;
};

Student.cpp

#include "Student.h"
using namespace std;
 
Student::Student():_name("Empty"),_age(0)
{
	cout << "Student Constructor" << endl;
}
 
Student::~Student()
{
	cout << "Student Destructor" << endl;
}
 
string Student::get_name()
{
	return _name;
}
 
void Student::set_name(string name)
{
	_name = name;
}
 
unsigned Student::get_age()
{
	return _age;
}
 
void Student::set_age(unsigned age)
{
	_age = age;
}
 
void Student::print()
{
	cout << "name :" << _name << " age : " << _age << endl;
}

StudentRegFunc.h

#pragma once
 
#include "Student.h"
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
 
//------定義相關(guān)的全局函數(shù)------
//創(chuàng)建對(duì)象
int lua_create_new_student(lua_State* L);
 
//get/set函數(shù)
int lua_get_name(lua_State* L);
int lua_set_name(lua_State* L);
int lua_get_age(lua_State* L);
int lua_set_age(lua_State* L);
 
//打印函數(shù)
int lua_print(lua_State* L);
 
//------注冊(cè)全局函數(shù)供Lua使用------
static const luaL_Reg lua_reg_student_funcs[] = {
	{ "create", lua_create_new_student },
	{ "get_name", lua_get_name },
	{ "set_name", lua_set_name },
	{ "get_age", lua_get_age },
	{ "set_age", lua_set_age },
	{ "print", lua_print },
	{ NULL, NULL },
};
 
int luaopen_student_libs(lua_State* L); 

StudentRegFunc.cpp

#include "StudentRegFunc.h"
 
int lua_create_new_student(lua_State* L)
{
	//創(chuàng)建一個(gè)對(duì)象指針?lè)诺絪tack里,返回給Lua中使用
	Student** s = (Student**)lua_newuserdata(L, sizeof(Student*));
	*s = new Student();
	return 1;
}
 
int lua_get_name(lua_State* L)
{
	//得到第一個(gè)傳入的對(duì)象參數(shù)(在stack最底部)
	Student** s = (Student**)lua_touserdata(L, 1);
	luaL_argcheck(L, s != NULL, 1, "invalid user data");
 
	//清空stack
	lua_settop(L, 0);
 
	//將數(shù)據(jù)放入stack中,供Lua使用
	lua_pushstring(L, (*s)->get_name().c_str());
 
	return 1;
}
 
int lua_set_name(lua_State* L)
{
	//得到第一個(gè)傳入的對(duì)象參數(shù)
	Student** s = (Student**)lua_touserdata(L, 1);
	luaL_argcheck(L, s != NULL, 1, "invalid user data");
 
	luaL_checktype(L, -1, LUA_TSTRING);
 
	std::string name = lua_tostring(L, -1);
	(*s)->set_name(name);
 
	return 0;
}
 
int lua_get_age(lua_State* L)
{
	Student** s = (Student**)lua_touserdata(L, 1);
	luaL_argcheck(L, s != NULL, 1, "invalid user data");
 
	lua_pushinteger(L, (*s)->get_age());
 
	return 1;
}
 
int lua_set_age(lua_State* L)
{
	Student** s = (Student**)lua_touserdata(L, 1);
	luaL_argcheck(L, s != NULL, 1, "invalid user data");
 
	luaL_checktype(L, -1, LUA_TNUMBER);
 
	(*s)->set_age((unsigned)lua_tointeger(L, -1));
 
	return 0;
}
 
int lua_print(lua_State* L)
{
	Student** s = (Student**)lua_touserdata(L, 1);
	luaL_argcheck(L, s != NULL, 1, "invalid user data");
 
	(*s)->print();
 
	return 0;
}
 
int luaopen_student_libs(lua_State* L)
{
	// 創(chuàng)建一張新的表,并把列表的函數(shù)注冊(cè)進(jìn)去
	luaL_newlib(L, lua_reg_student_funcs);
	return 1;
}

main.cpp

#include <iostream>
using namespace std;
 
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
 
#include "Student.h"
#include "StudentRegFunc.h"
 
static const luaL_Reg lua_reg_libs[] = {
	{ "base", luaopen_base }, //系統(tǒng)模塊
	{ "Student", luaopen_student_libs}, //模塊名字Student,注冊(cè)函數(shù)luaopen_student_libs
	{ NULL, NULL }
};
 
int main(int argc, char* argv[])
{
	if (lua_State* L = luaL_newstate()) {
 
		//注冊(cè)讓lua使用的庫(kù)
		const luaL_Reg* lua_reg = lua_reg_libs;
		for (; lua_reg->func; ++lua_reg) {
			luaL_requiref(L, lua_reg->name, lua_reg->func, 1);
			lua_pop(L, 1);
		}
		//加載腳本,如果出錯(cuò),則打印錯(cuò)誤
		if (luaL_dofile(L, "lua4.lua")) {
			cout << lua_tostring(L, -1) << endl;
		}
 
		lua_close(L);
	}
	else {
		cout << "luaL_newstate error !" << endl;
	}
 
	system("pause");
 
	return 0;
}
tolua

第二種方式是tolua,也就是tolua++
在cocos2dx中,基本都是用這種方式

//.h
class CMD_Data : public cocos2d::Ref
{
public:
	CMD_Data(unsigned short nlength);
	virtual ~CMD_Data();
public:
	void setMainCmdAndSubCmd(const unsigned short mainCmd, const unsigned short subCmd);
    unsigned short getMainCmd();
    unsigned short getSubCmd();
public:
	static CMD_Data *create(const int nLenth);
    //...
}

//.cpp

void CMD_Data::setMainCmdAndSubCmd(const unsigned short mainCmd, const unsigned short  subCmd)
{
	m_wMainCmd = mainCmd;
	m_wSubCmd = subCmd;
}

CMD_Data * CMD_Data::create(const int nLenth)
{
	CMD_Data * pData = new(std::nothrow) CMD_Data(nLenth);
	if (pData)
	{
		//pData->autorelease();
		return pData;
	}
	CC_SAFE_DELETE(pData);
	return nullptr;
}

unsigned short CMD_Data::getMainCmd()
{
    return m_wMainCmd;
}

unsigned short CMD_Data::getSubCmd()
{
    return m_wSubCmd;
}

注冊(cè)
.h

#pragma once
#include "base/ccConfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}
#endif
int register_all_Cmd_Data();

.cpp

int register_all_Cmd_Data()
{
	auto engine = LuaEngine::getInstance();
	ScriptEngineManager::getInstance()->setScriptEngine(engine);
	lua_State* tolua_S = engine->getLuaStack()->getLuaState();

	tolua_usertype(tolua_S, "CMD_Data");
	tolua_cclass(tolua_S, "CMD_Data", "CMD_Data", "cc.Node", nullptr);
	tolua_beginmodule(tolua_S, "CMD_Data");
	tolua_function(tolua_S, "create", tolua_Cmd_Data_create);
	tolua_function(tolua_S, "setCmdInfo", tolua_Cmd_Data_setMainCmdAndSubCmd);
	tolua_function(tolua_S, "getMainCmd", tolua_Cmd_Data_getMainCmd);
	tolua_function(tolua_S, "getSubCmd", tolua_Cmd_Data_getSubCmd);
	tolua_function(tolua_S, "getBufferLength", tolua_Cmd_Data_getBufferLength);
	tolua_function(tolua_S, "getCurIndex", tolua_Cmd_Data_getCurIndex);
	tolua_function(tolua_S, "setSendMessageLength", tolua_Cmd_Data_setSendMessageLength);
		tolua_endmodule(tolua_S);

	std::string typeName = typeid(CMD_Data).name();
	g_luaType[typeName] = "CMD_Data";
	g_typeCast["CMD_Data"] = "CMD_Data";
	return 1;
}

int tolua_Cmd_Data_create(lua_State* tolua_S)
{
	int argc = lua_gettop(tolua_S);
	CMD_Data *data = nullptr;
	if (argc == 2)
	{
		int nLength = lua_tointeger(tolua_S, 2);
		data = CMD_Data::create(nLength);
	}
	else
	{
		CCLOG("error CMD_Data create");
	}
	int nID = (data) ? data->_ID : -1;
	int *pLuaID = (data) ? &data->_luaID : nullptr;

	toluafix_pushusertype_ccobject(tolua_S, nID, pLuaID, (void*)data, "Cmd_Data");
	return 1;
}

int tolua_Cmd_Data_setMainCmdAndSubCmd(lua_State* tolua_S)
{
	CMD_Data *cobj = (CMD_Data*)tolua_tousertype(tolua_S, 1, nullptr);
	if (cobj)
	{
		int argc = lua_gettop(tolua_S);
		if (argc == 3)
		{
			unsigned short mainCmd = (unsigned short)lua_tointeger(tolua_S, 2);
			unsigned short subCmd = (unsigned short)lua_tointeger(tolua_S, 3);
			cobj->setMainCmdAndSubCmd(mainCmd, subCmd);
		}
	}
	return 0;
}

int tolua_Cmd_Data_getMainCmd(lua_State* tolua_S)
{
	CMD_Data *cobj = (CMD_Data*)tolua_tousertype(tolua_S, 1, nullptr);
	if (cobj)
	{
		lua_pushinteger(tolua_S, cobj->getMainCmd());
		return 1;
	}
	return 0;
}

int tolua_Cmd_Data_getSubCmd(lua_State* tolua_S)
{
	CMD_Data *cobj = (CMD_Data*)tolua_tousertype(tolua_S, 1, nullptr);
	if (cobj)
	{
		lua_pushinteger(tolua_S, cobj->getSubCmd());
		return 1;
	}
	return 0;
}

cocos2dx 生成工具

方便的是,cocos2dx提供了一套轉(zhuǎn)換的工具。

在cocos2dx引擎目錄下有個(gè)tools的目錄,里面有tolua的文件夾。

它里面的大概結(jié)構(gòu)如下

# Lua與C++交互(二)———— 交互,cocos2dx學(xué)習(xí)之路,lua,交互,cocos2d

可以看得出來(lái),cocos2dx本身的類(lèi)都是用這個(gè)方法去實(shí)現(xiàn)的。

隨便打開(kāi)一個(gè)ini文件

[cocos2dx_ui]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cocos2dx_ui

# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = ccui

# the native namespace in which this module locates, this parameter is used for avoid conflict of the same class name in different modules, as "cocos2d::Label" <-> "cocos2d::ui::Label".
cpp_namespace = cocos2d::ui

android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/%(gnu_libstdc_version)s/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/%(gnu_libstdc_version)s/include
android_flags = -D_SIZE_T_DEFINED_ 

clang_headers = -I%(clangllvmdir)s/%(clang_lib_version)s/clang/%(clang_version)s/include
clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__

cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android

cocos_flags = -DANDROID

cxxgenerator_headers = 

# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s 

# what headers to parse
headers = %(cocosdir)s/cocos/ui/CocosGUI.h

# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = Helper Widget Layout Button CheckBox ImageView Text TextAtlas TextBMFont LoadingBar Slider TextField ScrollView ListView PageView LayoutParameter LinearLayoutParameter RelativeLayoutParameter Rich.* HBox VBox RelativeBox Scale9Sprite EditBox LayoutComponent AbstractCheckButton RadioButton RadioButtonGroup TabControl TabHeader

# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.

skip = *::[^visit$ copyWith.* onEnter.* onExit.* ^description$ getObjectType .*HSV onTouch.* onAcc.* onKey.* onRegisterTouchListener ccTouch.* (g|s)etDelegate],
        Widget::[addTouchEventListener addClickEventListener addCCSEventListener],
        LayoutParameter::[(s|g)etMargin],
        RichText::[setTagDescription removeTagDescription setOpenUrlHandler]

rename_functions = 

rename_classes =

# for all class names, should we remove something when registering in the target VM?
remove_prefix = 

# classes for which there will be no "parent" lookup
classes_have_no_parents = Helper

# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip =

# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes = Helper AbstractCheckButton

# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = no


prefix : 輸出的前綴,會(huì)連接到tolua類(lèi)型的函數(shù)名之前,例如 int cocos2dx_ui_xxx(lua_State* tolua_S);

target_namespace : 所有生成的類(lèi)都屬于這個(gè)表下 例如這個(gè)里面的 ccui.xxx

cpp_namespace : C++中的命名空間,自動(dòng)生成的代碼中會(huì)加上這個(gè)命名空間

android_headers : 這是安卓編譯的一些指令,不需要修改,照抄就行

android_flags : 這是安卓編譯的一些指令,不需要修改,照抄就行

clang_headers : 這是Clang的編譯指令,不需要修改,照抄就行

cocos_flags : 這是Clang的編譯指令,不需要修改,照抄就行

cocos_headers: cocos的頭文件搜索目錄

cocos_flags:照抄

cxxgenerator_headers : 不管

extra_arguments : 所有文件的搜索路徑

headers:這是需要解析的頭文件 會(huì)從這個(gè)文件中識(shí)別所有include的頭文件,并解析其中的類(lèi), 可以填多個(gè)文件 比如自己的文件的需要引用的頭文件

classes:需要生成哪些類(lèi)的接口,這里支持正則表達(dá)式

skip:跳過(guò)哪些類(lèi)和函數(shù),支持正則表達(dá)式,可以借鑒cocos的配置文件

rename_functions:重命名函數(shù)

rename_classes:重命名類(lèi)

abstract_classes:哪些類(lèi)沒(méi)有創(chuàng)建構(gòu)造函數(shù),需要手動(dòng)重寫(xiě)構(gòu)造函數(shù)

script_control_cpp:不管,一般都是no

可以生成自己的一個(gè)配置文件。

然后看下同樣目錄下的genbindings.py文件

# Lua與C++交互(二)———— 交互,cocos2dx學(xué)習(xí)之路,lua,交互,cocos2d

需要將自己的ini文件填入進(jìn)去。

然后運(yùn)行這個(gè)python文件,便會(huì)自動(dòng)生成。

一般如下

# Lua與C++交互(二)———— 交互,cocos2dx學(xué)習(xí)之路,lua,交互,cocos2d

手寫(xiě)調(diào)用

有人會(huì)說(shuō),為啥cocos里面還有類(lèi)似

# Lua與C++交互(二)———— 交互,cocos2dx學(xué)習(xí)之路,lua,交互,cocos2d

首先,工具腳本不是萬(wàn)能的,有些無(wú)法導(dǎo)出,例如Lambda表達(dá)式,例如某些回調(diào)函數(shù)。

void GameNetWorkManager::resumSocketByIp(const int socketMark, const std::string &serverIp, const int serverPort, const std::function<void(bool)> &callback)
{
	callback(m_socketManage->resumSocket(socketMark,serverIp,serverPort));
}

比如這個(gè)方法。

無(wú)法生成,我們就需要手寫(xiě)

int tolua_GameNetWorkManager_resumSocket(lua_State* tolua_S)
{
	int argc = 0;
	GameNetWorkManager* cobj = nullptr;
	bool ok = true;

#if COCOS2D_DEBUG >= 1
	tolua_Error tolua_err;
#endif


#if COCOS2D_DEBUG >= 1
	if (!tolua_isusertype(tolua_S, 1, "GameNetWorkManager", 0, &tolua_err)) goto tolua_lerror;
#endif

	cobj = (GameNetWorkManager*)tolua_tousertype(tolua_S, 1, 0);

#if COCOS2D_DEBUG >= 1
	if (!cobj)
	{
		tolua_error(tolua_S, "invalid 'cobj' in function 'tolua_GameNetWorkManager_resumSocket'", nullptr);
		return 0;
	}
#endif

	argc = lua_gettop(tolua_S) - 1;
	if (argc == 2)
	{
		int arg1;
		ok &= luaval_to_int32(tolua_S, 2, (int *)&arg1, "GameNetWorkManager:resumSocket");
#if COCOS2D_DEBUG >= 1
		if (!toluafix_isfunction(tolua_S, 3, "LUA_FUNCTION", 0, &tolua_err))
		{
			goto tolua_lerror;
		}
#endif
		int handler = (toluafix_ref_function(tolua_S, 3, 0));
		if (!ok)
		{
			tolua_error(tolua_S, "invalid arguments in function 'tolua_GameNetWorkManager_resumSocket'", nullptr);
			return 0;
		}
		cobj->resumSocket(arg1,[=](bool resum)
		{
			LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
			stack->pushBoolean(resum);

			stack->executeFunctionByHandler(handler, 1);
			stack->clean();
			return 0;
		});
		ScriptHandlerMgr::getInstance()->addCustomHandler((void*)cobj, handler);
		lua_settop(tolua_S, 1);
		return 1;
	}
	else if (argc == 4)
	{
		int arg1;
		std::string arg2;
		int arg3;
		ok &= luaval_to_int32(tolua_S, 2, (int *)&arg1, "GameNetWorkManager:resumSocket");
		ok &= luaval_to_std_string(tolua_S, 3, &arg2, "GameNetWorkManager:resumSocket");
		ok &= luaval_to_int32(tolua_S, 4, (int *)&arg3, "GameNetWorkManager:resumSocket");
#if COCOS2D_DEBUG >= 1
		if (!toluafix_isfunction(tolua_S, 5, "LUA_FUNCTION", 0, &tolua_err))
		{
			goto tolua_lerror;
		}
#endif
		int handler = (toluafix_ref_function(tolua_S, 5, 0));
		if (!ok)
		{
			tolua_error(tolua_S, "invalid arguments in function 'tolua_GameNetWorkManager_resumSocket'", nullptr);
			return 0;
		}
		cobj->resumSocketByIp(arg1, arg2, arg3, [=](bool resum)
		{
			LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
			stack->pushBoolean(resum);

			stack->executeFunctionByHandler(handler, 1);
			stack->clean();
			return 0;
		});
		ScriptHandlerMgr::getInstance()->addCustomHandler((void*)cobj, handler);
		lua_settop(tolua_S, 1);
		return 1;
	}
	return 0;
#if COCOS2D_DEBUG >= 1
	tolua_lerror:
				tolua_error(tolua_S, "#ferror in function 'tolua_GameNetWorkManager_resumSocket'.", &tolua_err);
#endif

				return 0;
}

最后

如果需要深入了解Lua,強(qiáng)烈建議閱讀《lua設(shè)計(jì)與實(shí)現(xiàn)》。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-665845.html

到了這里,關(guān)于# Lua與C++交互(二)———— 交互的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 《入門(mén)級(jí)-Cocos2dx4.0 塔防游戲開(kāi)發(fā)》---第六課:歡迎界面開(kāi)發(fā)(四、自定義精靈)

    《入門(mén)級(jí)-Cocos2dx4.0 塔防游戲開(kāi)發(fā)》---第六課:歡迎界面開(kāi)發(fā)(四、自定義精靈)

    目錄 ?一、開(kāi)發(fā)環(huán)境 二、開(kāi)發(fā)內(nèi)容 2. 1 新建自定義精靈 2.2 在welcome中創(chuàng)建新的menu 2.3 消息綁定以及消息響應(yīng) 三、演示效果 四、知識(shí)點(diǎn) 4.1 內(nèi)部消息響應(yīng) 4.2 字體精靈說(shuō)明 4.3?CC_SYNTHESIZE宏 操作系統(tǒng):UOS1060專(zhuān)業(yè)版本。 cocos2dx:版本4.0 環(huán)境搭建教程:統(tǒng)信UOS下配置安裝cocos2dx開(kāi)發(fā)

    2024年02月11日
    瀏覽(27)
  • cocos2d-x C++與Lua交互

    cocos2d-x C++與Lua交互

    Cocos版本: 3.10 Lua版本: 5.1.4 環(huán)境: window Visual Studio 2013 Lua 作為一種腳本語(yǔ)言, 它的運(yùn)行需要有 宿主 的存在,通過(guò) Lua虛擬棧 進(jìn)行數(shù)據(jù)交互。 它的底層實(shí)現(xiàn)是 C 語(yǔ)言,C語(yǔ)言封裝了很多的API接口,使得C/C++與Lua之間可以很方便的通信交互。 Lua的官網(wǎng): https://www.lua.org/ 在coc

    2024年02月08日
    瀏覽(20)
  • cocos2d-x Android原生平臺(tái)與Lua交互

    版本: cocos2d-x 語(yǔ)言: C++/Java/Lua cocos2d-x原生平臺(tái)Android 接入第三方SDK, 需要了解 LuaJavaBridge 的使用。 它封裝了用于 Java 和 Lua 的相互調(diào)用, 其調(diào)用通過(guò) C++ 為中介,簡(jiǎn)要的流程: Lua調(diào)用Java: Lua - C++ - Java Java調(diào)用Lua: Java - C++ - Lua 以此方式來(lái)實(shí)現(xiàn)數(shù)據(jù)的交互, 接下來(lái)我們分別說(shuō)下

    2024年02月08日
    瀏覽(34)
  • Pygame和Cocos2d

    Pygame和Cocos2d都是 Python 中常用的游戲引擎,但它們的設(shè)計(jì)目標(biāo)、特點(diǎn)和使用場(chǎng)景略有不同。 Pygame與Cocos2d,目前是使用人數(shù)最多的兩個(gè)Python游戲庫(kù)。根據(jù)某知名產(chǎn)品點(diǎn)評(píng)網(wǎng)站的數(shù)據(jù)顯示,Cocos2d排名第一,Pygame排名第二。 Pygame是一種基于SDL(Simple DirectMedia Layer)的Python庫(kù),主要

    2024年01月21日
    瀏覽(31)
  • cocos2D插件轉(zhuǎn)3D插件

    cocos2D插件轉(zhuǎn)3D插件

    2024年02月16日
    瀏覽(23)
  • # Lua與C++交互(二)———— 交互

    # Lua與C++交互(二)———— 交互

    基礎(chǔ)調(diào)用 再來(lái)溫習(xí)一下 myName = “beauty girl” C++想要獲取myName的值,根據(jù)規(guī)則,它需要把myName壓入棧中,這樣lua就能看到; lua從堆棧中獲取myName的值,此時(shí)棧頂為空; lua拿著myName去全局表中查找與之對(duì)應(yīng)的字符串; 全局表找到,并返回\\\"beauty girl\\\"; lua把\\\"beauty girl\\\"壓入棧中;

    2024年02月11日
    瀏覽(26)
  • Cocos2d-x實(shí)現(xiàn)文字顏色漸變

    Cocos2d-x實(shí)現(xiàn)文字顏色漸變

    更改CCLabel文件的updateColor()函數(shù)中的頂點(diǎn)顏色即可,代碼如下: 效果圖: ?

    2024年02月12日
    瀏覽(30)
  • Lua與C++交互

    Lua與C++交互

    1、lua和c++交互機(jī)制是基于一個(gè)虛擬棧,C++和lua之間的所有數(shù)據(jù)交互都通過(guò)這個(gè)虛擬棧來(lái)完成,無(wú)論何時(shí)C++想從lua中調(diào)用一個(gè)值,被請(qǐng)求的值將會(huì)被壓入棧,C++想要傳遞一個(gè)值給Lua,首選將整個(gè)值壓棧,然后就可以在Lua中調(diào)用。 2、lua中提供正向和反向索引,區(qū)別在于證書(shū)永遠(yuǎn)

    2024年02月08日
    瀏覽(23)
  • 使用“Cocos引擎”創(chuàng)建的cpp工程如何在VS中調(diào)試Cocos2d-x源碼

    使用“Cocos引擎”創(chuàng)建的cpp工程如何在VS中調(diào)試Cocos2d-x源碼

    前段時(shí)間Cocos2d-x更新了一個(gè)Cocos引擎,這是一個(gè)集合源碼,IDE,Studio這一家老小的整合包,我們可以使用這個(gè)Cocos引擎來(lái)創(chuàng)建我們的項(xiàng)目。 在Cocos2d-x被整合到Cocos引擎之前,我們可以不那么方便地在我們創(chuàng)建的工程里調(diào)試Cocos2d-x的代碼,當(dāng)我們使用了整合后的Cocos引擎,調(diào)試

    2024年02月12日
    瀏覽(23)
  • Lua與C++交互(一)————堆棧

    Lua與C++交互(一)————堆棧

    什么是Lua虛擬機(jī) Lua本身是用C語(yǔ)言實(shí)現(xiàn)的,它是跨平臺(tái)語(yǔ)言,得益于它本身的Lua虛擬機(jī)。 虛擬機(jī)相對(duì)于物理機(jī),借助于操作系統(tǒng)對(duì)物理機(jī)器(CPU等硬件)的一種模擬、抽象,主要扮演CPU和內(nèi)存的作用。 虛擬機(jī)的主要職責(zé)就是:執(zhí)行字節(jié)碼中的指令,管理全局狀態(tài)(global_stat

    2024年02月11日
    瀏覽(28)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包