Quick 2.2.5 升级 v3 集成pb.c 运行错误(已经解决)

下载了最新的v3 code 在v3上集成pb,把pb.c 引入到 lua_extensions目录下,让后在lua_extensions.c文件头部添加 #include “protobuf/pb.c”
在 luaopen_lua_extensions 中添加 luaopen_pb(L);
编译运行player 运行起来错误。


cocos2d:  /Users/xxx/Library/Developer/Xcode/DerivedData/player-azcpeuetgyksyidkhopysafxltby/Build/Products/Debug/player.app/Contents/Resources/player.lua:171: attempt to index field 'Node' (a nil value)
cocos2d: 
{
 gl.supports_vertex_array_object: true
 cocos2d.x.version: cocos2d-x 3.2
 gl.vendor: NVIDIA Corporation
 gl.supports_PVRTC: false
 gl.renderer: NVIDIA GeForce GT 640M OpenGL Engine
 cocos2d.x.compiled_with_profiler: false
 gl.max_texture_size: 16384
 gl.supports_ETC1: false
 gl.supports_BGRA8888: false
 cocos2d.x.build_type: DEBUG
 gl.supports_discard_framebuffer: false
 gl.supports_NPOT: true
 gl.supports_S3TC: true
 gl.version: 2.1 NVIDIA-8.26.21 310.40.35f08
 gl.supports_ATITC: false
 gl.max_texture_units: 16
 cocos2d.x.compiled_with_gl_state_cache: true
}




libpng warning: iCCP: known incorrect sRGB profile
cocos2d:  function name '__PLAYER_OPEN__' not found
cocos2d: value at stack -3] is not function
cocos2d: lua_loadChunksFromZIP() - load zip file: /Users/xxx/Documents/quick-x-v3/quick/lib/framework_precompiled/framework_precompiled.zip
cocos2d: lua_loadChunksFromZIP() - loaded chunks count: 69
cocos2d:  ===========================================================
cocos2d:                LOAD QUICK FRAMEWORK
cocos2d:  ===========================================================
cocos2d:  :0: attempt to index field 'Node' (a nil value)
cocos2d:  ----------------------------------------

cocos2d:  LUA ERROR: /Users/xxx/Library/Developer/Xcode/DerivedData/player-azcpeuetgyksyidkhopysafxltby/Build/Products/Debug/player.app/Contents/Resources/player.lua:201: attempt to index field 'HTTPRequest' (a nil value)

注释 luaopen_pb(L); 运行正常。

在阳光七月大牛的帮助下解决了这个问题,3.0上加载第三方库时需要清理堆栈 在调用 luaopen_pb(L); 后面加上 lua_pop(L, 2);就解决了。

忘了说重要的一点,必须用 quick 版的 binding-generator,地址是:

https://github.com/dualface/binding-generator-quick

。。。。。。

向V3.0集成自己的模块时,如果以前已经用tolua做过导出,有tolua文件,也是可以用tolua进行集成的。具体可以参考quick/lib/extra/luabinding目录下的绑定方式。

这块没有pb.c 是网上直接绑定好了的,难道需要从google 上再下一个?

一般绑定好的代码,做些小的修改就可以了。你原来是怎么绑定的呢?

这个是pb.c

#include <stdint.h>
#include <string.h>


#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <CCPlatformConfig.h>


#if WIN32
#define __LITTLE_ENDIAN 1234
#define __BYTE_ORDER __LITTLE_ENDIAN


#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <endian.h>
#else
    #include <machine/endian.h>
#endif


 
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define IS_LITTLE_ENDIAN
#endif


#define IOSTRING_META "protobuf.IOString"


#define checkiostring(L) \
    (IOString*) luaL_checkudata(L, 1, IOSTRING_META)


#define IOSTRING_BUF_LEN 65535


typedef struct{
    size_t size;
    char buf;
} IOString;


static void pack_varint(luaL_Buffer *b, uint64_t value)
{
    if (value >= 0x80)
    {
        luaL_addchar(b, value | 0x80);
        value >>= 7;
        if (value >= 0x80)
        {
            luaL_addchar(b, value | 0x80);
            value >>= 7;
            if (value >= 0x80)
            {
                luaL_addchar(b, value | 0x80);
                value >>= 7;
                if (value >= 0x80)
                {
                    luaL_addchar(b, value | 0x80);
                    value >>= 7;
                    if (value >= 0x80)
                    {
                        luaL_addchar(b, value | 0x80);
                        value >>= 7;
                        if (value >= 0x80)
                        {
                            luaL_addchar(b, value | 0x80);
                            value >>= 7;
                            if (value >= 0x80)
                            {
                                luaL_addchar(b, value | 0x80);
                                value >>= 7;
                                if (value >= 0x80)
                                {
                                    luaL_addchar(b, value | 0x80);
                                    value >>= 7;
                                    if (value >= 0x80)
                                    {
                                        luaL_addchar(b, value | 0x80);
                                        value >>= 7;
                                    } 
                                } 
                            } 
                        } 
                    } 
                } 
            } 
        } 
    }
    luaL_addchar(b, value);
} 


static int varint_encoder(lua_State *L)
{
    lua_Number l_value = luaL_checknumber(L, 2);
    uint64_t value = (uint64_t)l_value;


    luaL_Buffer b;
    luaL_buffinit(L, &b);
 
    pack_varint(&b, value);


    lua_settop(L, 1);
    luaL_pushresult(&b);
    lua_call(L, 1, 0);
    return 0;
}


static int signed_varint_encoder(lua_State *L)
{
    lua_Number l_value = luaL_checknumber(L, 2);
    int64_t value = (int64_t)l_value;
 
    luaL_Buffer b;
    luaL_buffinit(L, &b);


    if (value < 0)
    {
        pack_varint(&b, *(uint64_t*)&value);
    }else{
        pack_varint(&b, value);
    }
 
    lua_settop(L, 1);
    luaL_pushresult(&b);
    lua_call(L, 1, 0);
    return 0;
}


static int pack_fixed32(lua_State *L, uint8_t* value){
#ifdef IS_LITTLE_ENDIAN
    lua_pushlstring(L, (char*)value, 4);
#else
    uint32_t v = htole32(*(uint32_t*)value);
    lua_pushlstring(L, (char*)&v, 4);
#endif
    return 0;
}


static int pack_fixed64(lua_State *L, uint8_t* value){
#ifdef IS_LITTLE_ENDIAN
    lua_pushlstring(L, (char*)value, 8);
#else
    uint64_t v = htole64(*(uint64_t*)value);
    lua_pushlstring(L, (char*)&v, 8);
#endif
    return 0;
}


static int struct_pack(lua_State *L)
{
    uint8_t format = luaL_checkinteger(L, 2);
    lua_Number value = luaL_checknumber(L, 3);
    lua_settop(L, 1);


    switch(format){
        case 'i':
            {
                int32_t v = (int32_t)value;
                pack_fixed32(L, (uint8_t*)&v);
                break;
            }
        case 'q':
            {
                int64_t v = (int64_t)value;
                pack_fixed64(L, (uint8_t*)&v);
                break;
            }
        case 'f':
            {
                float v = (float)value;
                pack_fixed32(L, (uint8_t*)&v);
                break;
            }
        case 'd':
            {
                double v = (double)value;
                pack_fixed64(L, (uint8_t*)&v);
                break;
            }
        case 'I':
            {
                uint32_t v = (uint32_t)value;
                pack_fixed32(L, (uint8_t*)&v);
                break;
            }
        case 'Q':
            {
                uint64_t v = (uint64_t) value;
                pack_fixed64(L, (uint8_t*)&v);
                break;
            }
        default:
            luaL_error(L, "Unknown, format");
    }
    lua_call(L, 1, 0);
    return 0;
}


static size_t size_varint(const char* buffer, size_t len)
{
    size_t pos = 0;
    while(buffer & 0x80){
        ++pos;
        if(pos > len){
            return -1;
        }
    }
    return pos+1;
}


static uint64_t unpack_varint(const char* buffer, size_t len)
{
    uint64_t value = buffer & 0x7f;
    size_t shift = 7;
    size_t pos=0;
    for(pos = 1; pos < len; ++pos)
    {
        value |= ((uint64_t)(buffer & 0x7f)) << shift;
        shift += 7;
    }
    return value;
}


static int varint_decoder(lua_State *L)
{
    size_t len;
    const char* buffer = luaL_checklstring(L, 1, &len);
    size_t pos = luaL_checkinteger(L, 2);
 
    buffer += pos;
    len = size_varint(buffer, len);
    if(len == -1){
        luaL_error(L, "error data %s, len:%d", buffer, len);
    }else{
        lua_pushnumber(L, (lua_Number)unpack_varint(buffer, len));
        lua_pushinteger(L, len + pos);
    }
    return 2;
}


static int signed_varint_decoder(lua_State *L)
{
    size_t len;
    const char* buffer = luaL_checklstring(L, 1, &len);
    size_t pos = luaL_checkinteger(L, 2);
    buffer += pos;
    len = size_varint(buffer, len);
 
    if(len == -1){
        luaL_error(L, "error data %s, len:%d", buffer, len);
    }else{
        lua_pushnumber(L, (lua_Number)(int64_t)unpack_varint(buffer, len));
        lua_pushinteger(L, len + pos);
    }
    return 2;
}


static int zig_zag_encode32(lua_State *L)
{
    int32_t n = luaL_checkinteger(L, 1);
    uint32_t value = (n << 1) ^ (n >> 31);
    lua_pushinteger(L, value);
    return 1;
}


static int zig_zag_decode32(lua_State *L)
{
    uint32_t n = (uint32_t)luaL_checkinteger(L, 1);
    int32_t value = (n >> 1) ^ - (int32_t)(n & 1);
    lua_pushinteger(L, value);
    return 1;
}


static int zig_zag_encode64(lua_State *L)
{
    int64_t n = (int64_t)luaL_checknumber(L, 1);
    uint64_t value = (n << 1) ^ (n >> 63);
    lua_pushinteger(L, value);
    return 1;
}


static int zig_zag_decode64(lua_State *L)
{
    uint64_t n = (uint64_t)luaL_checknumber(L, 1);
    int64_t value = (n >> 1) ^ - (int64_t)(n & 1);
    lua_pushinteger(L, value);
    return 1;
}


static int read_tag(lua_State *L)
{
    size_t len;
    const char* buffer = luaL_checklstring(L, 1, &len);
    size_t pos = luaL_checkinteger(L, 2);
 
    buffer += pos;
    len = size_varint(buffer, len);
    if(len == -1){
        luaL_error(L, "error data %s, len:%d", buffer, len);
    }else{
        lua_pushlstring(L, buffer, len);
        lua_pushinteger(L, len + pos);
    }
    return 2;
}


static const uint8_t* unpack_fixed32(const uint8_t* buffer, uint8_t* cache)
{
#ifdef IS_LITTLE_ENDIAN
    return buffer;
#else
    *(uint32_t*)cache = le32toh(*(uint32_t*)buffer);
    return cache;
#endif
}


static const uint8_t* unpack_fixed64(const uint8_t* buffer, uint8_t* cache)
{
#ifdef IS_LITTLE_ENDIAN
    return buffer;
#else
    *(uint64_t*)cache = le64toh(*(uint64_t*)buffer);
    return cache;
#endif
}


static int struct_unpack(lua_State *L)
{
 size_t len;
 uint8_t format;
 const uint8_t* buffer;
 size_t pos;
 uint8_t out;


    format = luaL_checkinteger(L, 1);
    buffer = (uint8_t*)luaL_checklstring(L, 2, &len);
    pos = luaL_checkinteger(L, 3);


    buffer += pos;
    switch(format){
        case 'i':
            {
                lua_pushinteger(L, *(int32_t*)unpack_fixed32(buffer, out));
                break;
            }
        case 'q':
            {
                lua_pushnumber(L, (lua_Number)*(int64_t*)unpack_fixed64(buffer, out));
                break;
            }
        case 'f':
            {
                lua_pushnumber(L, (lua_Number)*(float*)unpack_fixed32(buffer, out));
                break;
            }
        case 'd':
            {
                lua_pushnumber(L, (lua_Number)*(double*)unpack_fixed64(buffer, out));
                break;
            }
        case 'I':
            {
                lua_pushnumber(L, *(uint32_t*)unpack_fixed32(buffer, out));
                break;
            }
        case 'Q':
            {
                lua_pushnumber(L, (lua_Number)*(uint64_t*)unpack_fixed64(buffer, out));
                break;
            }
        default:
            luaL_error(L, "Unknown, format");
    }
    return 1;
}


static int iostring_new(lua_State* L)
{
    IOString* io = (IOString*)lua_newuserdata(L, sizeof(IOString));
    io->size = 0;


    luaL_getmetatable(L, IOSTRING_META);
    lua_setmetatable(L, -2); 
    return 1;
}


static int iostring_str(lua_State* L)
{
    IOString *io = checkiostring(L);
    lua_pushlstring(L, io->buf, io->size);
    return 1;
}


static int iostring_len(lua_State* L)
{
    IOString *io = checkiostring(L);
    lua_pushinteger(L, io->size);
    return 1;
}


static int iostring_write(lua_State* L)
{
    IOString *io = checkiostring(L);
    size_t size;
    const char* str = luaL_checklstring(L, 2, &size);
    if(io->size + size > IOSTRING_BUF_LEN){
        luaL_error(L, "Out of range");
    }
    memcpy(io->buf + io->size, str, size);
    io->size += size;
    return 0;
}


static int iostring_sub(lua_State* L)
{
    IOString *io = checkiostring(L);
    size_t begin = luaL_checkinteger(L, 2);
    size_t end = luaL_checkinteger(L, 3);


    if(begin > end || end > io->size)
    {
        luaL_error(L, "Out of range");
    }
    lua_pushlstring(L, io->buf + begin - 1, end - begin + 1);
    return 1;
}


static int iostring_clear(lua_State* L)
{
    IOString *io = checkiostring(L);
    io->size = 0; 
    return 0;
}


static const struct luaL_reg _pb ] = {
    {"varint_encoder", varint_encoder},
    {"signed_varint_encoder", signed_varint_encoder},
    {"read_tag", read_tag},
    {"struct_pack", struct_pack},
    {"struct_unpack", struct_unpack},
    {"varint_decoder", varint_decoder},
    {"signed_varint_decoder", signed_varint_decoder},
    {"zig_zag_decode32", zig_zag_decode32},
    {"zig_zag_encode32", zig_zag_encode32},
    {"zig_zag_decode64", zig_zag_decode64},
    {"zig_zag_encode64", zig_zag_encode64},
    {"new_iostring", iostring_new},
    {NULL, NULL}
};


static const struct luaL_reg _c_iostring_m ] = {
    {"__tostring", iostring_str},
    {"__len", iostring_len},
    {"write", iostring_write},
    {"sub", iostring_sub},
    {"clear", iostring_clear},
    {NULL, NULL}
};


int luaopen_pb (lua_State *L)
{
    luaL_newmetatable(L, IOSTRING_META);
    lua_pushvalue(L, -1);
    lua_setfield(L, -2, "__index");
    luaL_register(L, NULL, _c_iostring_m);


    luaL_register(L, "pb", _pb);
    return 1;
} 


void luaopen_lua_extensions(lua_State L)
{
// load extensions
luaL_Reg
lib = luax_exts;
lua_getglobal(L, “package”);
lua_getfield(L, -1, “preload”);
for (; lib->func; lib++)
{
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 2);

// load extensions script
luaopen_socket_scripts(L);

luaopen_pb(L);

}

你这是纯CAPI绑定,应该没什么问题啊

是啊 但是 一加上 luaopen_pb(L); 运行player起来就出错。

2.2.5之前的版本都是正常的。