1. 程式人生 > >[lua/unity/cocos2dx]關於雲風pbc不支援int64的解決辦法

[lua/unity/cocos2dx]關於雲風pbc不支援int64的解決辦法

其實這個很簡單,因為原始碼都有,改改就好,但是估計有些人很擔心改了之後出現各種問題解決不了,我通常是先改,出問題再說,哈哈。不過其實去看看原始碼,雲風的程式碼還是寫的很清晰的

以上是廢話

找到pbc-lua.c

搜尋case PBC_INT64

會發現這裡對於int64的處理直接處理成了lua_Number,那麼這裡就可以根據個人需求來修改了。不過看pbc其他地方的處理,會發現其他地方通過luastring來處理,其實為了減小依賴,這樣最方便

大致的程式碼是這樣

case PBC_INT64: {
		uint64_t v64 = (uint64_t)(v->i.hi) << 32 | (uint64_t)(v->i.low);
		//lua_pushnumber(L,(lua_Number)(int64_t)v64);//原本的實現
		lua_pushlstring(L, (const char *)&v64, sizeof(v64));
		break;
	}


這裡其實就是把值設定到一個table裡

廢話一下

有些C/C++基礎不好的人看到這個就納悶了,我需要的是int64,你給我弄成字串是什麼意思?

熟悉這些的自然不用解釋,如果你注意看就會發現這裡沒有用sprintf而是直接指標強轉。對於直接操作記憶體的語言來說,其實只要記憶體的值是一樣的,管你是什麼型別,型別只是方便操作的工具而已。

問題來了,這樣在lua裡是用不了的,怎麼辦?

其實很簡單,因為lua51是不支援int64的,那麼肯定要自己實現int64的支援,就拿cocos2dx為例,其內建裡一個Integer64類,用於lua處理int64

對於cocos2dx,我是這樣處理的,找到Integer64.h,在函式toLua_integer64裡面加入

static int toLua_Integer64(lua_State* L)
{
	int argc = lua_gettop(L);

	if(argc == 0)
	{
		return new_Integer64(L,0);
	}
	else if (argc == 1)
	{
		int64_t tmpdata = 0;
		if (lua_type(L, 1)== LUA_TSTRING) {
			size_t len = 0;
			const char * number = lua_tolstring(L, 1, &len);
			if (len != 8) {
				return luaL_error(L, "Need an 8 length string for int64");
			}
			tmpdata = *(int64_t*)number;
		}
		else {
			tmpdata = (int64_t)lua_tonumber(L, 1);
		}
		return new_Integer64(L,tmpdata);
	}
	return 0;
}

加入pb檔案這樣定義

mytest{
optional int64 value = 1;
}


lua那邊的使用:

local r = protobuf.decode("mypbtest",databuffer)
local v64 = Interger64.new(r.value)
print("An int64 value:"..v64)


Unity同理,自己實現一個int64支援就好