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

本文介绍如何将C++中的SocketUtil接口导出到Lua,并实现消息发送与接收的功能。通过编写配置文件和特殊函数绑定代码,最终在Lua环境中成功调用C++接口。

本节记录下将 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–

内容概要:本文介绍了一种用于电磁暂态(EMT)研究的第四类全变流器型风力发电系统的通用Simulink仿真模型,旨在构建一个能够准确反映实际风电系统动态特性的简化通用模型。该模型涵盖了风力机、传动链、发电机、全功率变流器及其控制策略等关键组成部分,重点突出系统在电网故障、风速波动等复杂工况下的动态响应能力,适用于风电并网电磁暂态分析、新型电力系统稳定性评估及高比例可再生能源接入场景的研究。模型设计兼顾准确性与仿真效率,便于研究人员快速搭建和调试,推动风电系统建模与控制技术的发展; 适合人群:具备一定电力系统理论基础和MATLAB/Simulink仿真能力,从事新能源发电、电力电子变换、风电并网控制及相关方向的研究生、科研人员及工程技术人员; 使用场景及目标:①开展风电系统在电网扰动下的电磁暂态仿真分析;②研究全功率变流器风电机组的动态行为与控制特性;③支撑新型电力系统中高渗透率风电接入的稳定性与电能质量评估,服务于学术研究、课程教学与工程项目前期仿真验证; 阅读建议:建议读者结合文中提供的模型结构与参数设置,在Simulink环境中动手复现并调试仿真模型,通过设置不同运行工况(如三相短路、低电压穿越、风速突变等)观察系统响应,深入理解全变流器风电机组的建模方法、控制逻辑与动态特性,进而拓展应用于更复杂的多机并网或综合能源系统仿真场景。
内容概要:本文探讨了Hash算法在芯片行业,特别是网络处理器(NPU)中的性能优化实践,聚焦于如何通过硬件流水线设计实现纳秒级高速哈希查找。文章分析了传统软件哈希方案在高带宽场景下的局限性,提出基于硬件描述语言或高层次综合(HLS)的设计方法,采用CRC32等硬件友好型哈希函数、并行多路哈希、流水线化解耦以及双端口存储结构等核心技术,实现低延迟、无阻塞的数据包处理。通过C++风格的HLS代码示例,展示了从算法选择到资源优化的完整硬件加速逻辑,并深入剖析了循环展开、位宽控制、内存映射和流水线调度等关键实现细节。最后展望了可编程交换机、P4语言支持及TCAM与哈希混合架构等未来发展方向。; 适合人群:具备数字电路基础、熟悉Verilog/SystemVerilog或HLS的芯片设计工程师,以及从事网络芯片、FPGA加速、高性能路由设备研发的技术人员(工作年限1-5年为宜);也适合对硬件加速算法感兴趣的研究人员。; 使用场景及目标:①掌握如何将哈希算法高效映射到硬件逻辑中以满足线速转发需求;②理解流水线设计、资源约束优化、读写冲突规避等在实际芯片项目中的应用;③为开发高性能网络处理器中的流表/路由表查找单元提供技术参考与实现范例。; 阅读建议:学习时应结合HLS工具(如Xilinx Vitis HLS)进行代码仿真与综合,重点关注#pragma指令对硬件结构的影响,并对比不同哈希算法在资源占用与时序表现上的差异,深入理解“空间换时间”的硬件优化本质。
内容概要:本文系统研究了基于粒子群优化(PSO)、灰狼优化(GWO)、鲸鱼优化(WOA)、哈里斯鹰优化(HHO)、蜣螂优化(DBO)和麻雀搜索算法(SSA)六种智能优化算法在无人机三维路径规划中的应用,并在Matlab平台上实现了相应的仿真代码。研究构建了复杂的三维地形与障碍物环境模型,设计了包含路径长度、飞行时间、能耗及安全性等多维度的成本函数,通过定义合理的适应度函数与飞行约束条件,对各类算法的路径搜索能力、收敛速度与规划质量进行了全面对比分析。通过仿真实验验证了各算法在静态复杂环境下的性能表现,旨在为实际无人机任务中优化算法的选择提供科学依据和技术支持。; 适合人群:具备一定Matlab编程基础,从事智能优化算法、无人机路径规划、自动化控制及相关领域研究的研究生、科研人员或工程技术人员。; 使用场景及目标:① 掌握主流群智能优化算法在无人机三维路径规划中的建模与实现方法;② 对比分析不同算法在相同复杂环境下的性能差异,为算法选型提供量化依据;③ 为后续研究动态环境路径规划、多无人机协同任务分配等问题奠定理论与技术基础; 阅读建议:建议读者结合提供的Matlab代码逐模块分析算法实现流程,重点关注适应度函数的设计、障碍物规避策略的实现以及多目标成本函数的权衡机制,同时可通过调整参数设置或引入新型优化算法进行扩展实验,以深化对算法性能的理解与实际应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值