Cocos2d-x Tutorial 之 Socket的使用(2)

本节记录下将 C++ 版本的接口,倒出到 Lua ,并在 Lua 中发送和接收消息

一、编写 cocos2dx_socket_util.ini 文件

参考Cocos2d-x Tutorial 之 如何绑定 C++ 类到 Lua

此处贴出改写完成以后的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
[cocos2dx_socket_util]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cocos2dx_socket_util

# 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 = 




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

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

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

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/../runtime-src/Classes/SocketUtil.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 = SocketUtil

# 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 = SocketUtil::[addMsgHandler addStateHandler addMsgHandlerLua addStateHandlerLua receiveMsg socketStateChange]






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 = 

# 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 = 

# 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

二、编写 genbindings_socket_util.py 文件并生成绑定代码

参考Cocos2d-x Tutorial 之 如何绑定 C++ 类到 Lua

此处贴出改写完成以后的内容

1
2
3
4
5
6
7
...
        output_dir = '%s/../runtime-src/Classes/auto' % project_root

        cmd_args = {
                    'cocos2dx_socket_util.ini' : ('cocos2dx_socket_util', 'lua_cocos2dx_socket_util_auto'), \
                    }
...

打开终端,进入到 genbindings_socket_util.py 所在目录,执行如下命令生成代码

1
./genbindings_socket_util.py

检查是否有报错,没有报错说明代码生成成功。

三、编写特殊函数的绑定代码

SocketUtil 中包含了两个特殊一点的函数,需要从 Lua 中传递一个函数的引用,到 C++ 中,需要手动绑定一下。

在 auto 文件夹所在目录 创建一个新的文件夹 manual,拷贝如下代码。

lua_cocos2dx_socket_util_manual.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "base/ccConfig.h"
#ifndef __cocos2dx_socket_util_manual_h__
#define __cocos2dx_socket_util_manual_h__

#ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}
#endif

int register_all_cocos2dx_socket_util_manual(lua_State* tolua_S);











#endif // __cocos2dx_socket_util_manual_h__

lua_cocos2dx_socket_util_manual.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "lua_cocos2dx_socket_util_manual.hpp"
#include "SocketUtil.h"
#include "tolua_fix.h"
#include "LuaBasicConversions.h"
#include "CCLuaValue.h"


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

#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif


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

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

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

    argc = lua_gettop(tolua_S)-1;
    if (argc == 1)
    {
        LUA_FUNCTION arg0;
        do {
            arg0 = toluafix_ref_function(tolua_S,2,0);
        } while(0)
        ;
        if(!ok)
        {
            tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_socket_util_SocketUtil_addStateHandlerLua'", nullptr);
            return 0;
        }
        cobj->addStateHandlerLua(arg0);
        return 0;
    }
    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "SocketUtil:addStateHandlerLua",argc, 1);
    return 0;

#if COCOS2D_DEBUG >= 1
    tolua_lerror:
    tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_socket_util_SocketUtil_addStateHandlerLua'.",&tolua_err);
#endif

    return 0;
}
int lua_cocos2dx_socket_util_SocketUtil_addMsgHandlerLua(lua_State* tolua_S)
{
    int argc = 0;
    SocketUtil* cobj = nullptr;
    bool ok  = true;

#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif


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

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

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

    argc = lua_gettop(tolua_S)-1;
    if (argc == 1)
    {
        LUA_FUNCTION arg0;

        do {
            arg0 = toluafix_ref_function(tolua_S,2,0);
        } while(0)
        ;
        if(!ok)
        {
            tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_socket_util_SocketUtil_addMsgHandlerLua'", nullptr);
            return 0;
        }
        cobj->addMsgHandlerLua(arg0);
        return 0;
    }
    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "SocketUtil:addMsgHandlerLua",argc, 1);
    return 0;

#if COCOS2D_DEBUG >= 1
    tolua_lerror:
    tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_socket_util_SocketUtil_addMsgHandlerLua'.",&tolua_err);
#endif

    return 0;
}

int lua_register_cocos2dx_socket_util_SocketUtil_Manual(lua_State* tolua_S)
{
    tolua_usertype(tolua_S,"SocketUtil");
    tolua_cclass(tolua_S,"SocketUtil","SocketUtil","cc.Ref",nullptr);

    tolua_beginmodule(tolua_S,"SocketUtil");
        tolua_function(tolua_S,"addStateHandlerLua",lua_cocos2dx_socket_util_SocketUtil_addStateHandlerLua);
        tolua_function(tolua_S,"addMsgHandlerLua",lua_cocos2dx_socket_util_SocketUtil_addMsgHandlerLua);
    tolua_endmodule(tolua_S);
    std::string typeName = typeid(SocketUtil).name();
    g_luaType[typeName] = "SocketUtil";
    g_typeCast["SocketUtil"] = "SocketUtil";
    return 1;
}
TOLUA_API int register_all_cocos2dx_socket_util_manual(lua_State* tolua_S)
{
    tolua_open(tolua_S);

    tolua_module(tolua_S,nullptr,0);
    tolua_beginmodule(tolua_S,nullptr);

    lua_register_cocos2dx_socket_util_SocketUtil_Manual(tolua_S);

    tolua_endmodule(tolua_S);
    return 1;
}

四、注册绑定函数

将 Class 目录下的 auto 和 manual 文件夹 添加到项目中,修改 AppDelegate.cpp 文件。

1
2
3
4
5
6
7
8
9
10
11
12
...
#include "lua_cocos2dx_socket_util_auto.hpp"
#include "lua_cocos2dx_socket_util_manual.hpp"
...
bool AppDelegate::applicationDidFinishLaunching()
{
    ...
    register_all_cocos2dx_socket_util(stack->getLuaState());
    register_all_cocos2dx_socket_util_manual(stack->getLuaState());
    ...
}
...

五、测试

打开 src/app/scenes 下面的 MainScene.lua

添加测试代码

MainScene.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function MainScene:ctor()
    ...
    local instance = SocketUtil:getInstance()
    instance:addMsgHandlerLua(handler(self, MainScene.msgHandler))
    instance:addStateHandlerLua(handler(self, MainScene.stateHandler))
    instance:connectServer("127.0.0.1", 3000)
    scheduler.performWithDelayGlobal(function(dt)
            local str = "hello world"
            instance:sendMsg({string.byte(str,1,#str)})
        end, 2)
    scheduler.performWithDelayGlobal(function(dt)
            instance:close()
        end, 4)
end

function MainScene:msgHandler(bytes)
    print("msg")
end

function MainScene:stateHandler(connected)
    print("state: "..tostring(connected))
end

启动好服务端程序,运行,检查控制台输出

1
2
3
[LUA-print] state: true
[LUA-print] msg
[LUA-print] state: false

至此,SocketUtil 绑定到 Lua 完成。

–EOF–

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值