Boost(MSVC编译),使用信号槽。
天天看QT的信号槽,突然发现boost中也有信号槽,所以想试试boost的信号槽,尝试一下。需要先对boost进行编译,之后我会使用信号槽作为演示代码。
1 .打开msvc编译工具链

-
执行命令 cd 到你的boost 文件夹下 再执行bootstrap.bat msvc

-
编译安装boost
b2 install --build-type=complete threading=multi link=shared address-model=64 toolset=msvc-14.2
link 是动态库 如果你想编译静态库的话把link=shared 修改为link=static。
msvc版本号在C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC文件夹下的文件夹名称找。

- 到C:\Boost 内找到编译完成的库和头文件
Boost库的使用-信号槽
- 新建一个项目,用来测试boost
CMakeLists.txt 我的cmake里面有个预编译头,你不需要的话可以删除相关部分。不然可能会报错
cmake_minimum_required(VERSION 3.19)
project(BoostTest)
#指定C++标准
set(CMAKE_CXX_STANDARD 17)
#指定输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/output)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/output)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/output)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/output)
#自动编译QT文件
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
#开启包含当前编译目录
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#指定QT版本和对应的库
set(QT_VERSION 5)
set(REQUIRED_LIBS Core Gui Widgets)
set(REQUIRED_LIBS_QUALIFIED Qt5::Core Qt5::Gui Qt5::Widgets)
#寻找QT库
find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} REQUIRED)
#自动查找头文件路径函数
macro(FIND_INCLUDE_DIR result curdir) #定义函数,2个参数:存放结果result;指定路径curdir;
file(GLOB_RECURSE children "${curdir}/*.hpp" "${curdir}/*.h" ) #遍历获取{curdir}中*.hpp和*.h文件列表
file(GLOB SOURCE_INCLUDE ${children} ) #将文件放入 SOURCE_INCLUDE 中
set(dirlist "") #定义dirlist中间变量,并初始化
foreach(child ${children}) #for循环
string(REGEX REPLACE "(.*)/.*" "\\1" LIB_NAME ${child}) #字符串替换,用/前的字符替换/*h
if(IS_DIRECTORY ${LIB_NAME}) #判断是否为路径
list (FIND dirlist ${LIB_NAME} list_index) #判断dirlist是否含有${LIB_NAME}
if(${list_index} LESS 0)
LIST(APPEND dirlist ${LIB_NAME}) #将合法的路径加入dirlist变量中
else()
endif() #结束判断
endif()
endforeach() #结束for循环
set(${result} ${dirlist}) #dirlist结果放入result变量中
endmacro()
#自动查找源文件路径函数
macro(FIND_SRC_DIR result curdir)
file(GLOB_RECURSE children "${curdir}/*.cpp" "${curdir}/*.cc")
file(GLOB SOURCE_SRC ${children} )
set(dirlist "")
foreach(child ${children})
string(REGEX REPLACE "(.*)/.*" "\\1" LIB_NAME ${child})
if(IS_DIRECTORY ${LIB_NAME})
list (FIND dirlist ${LIB_NAME} list_index)
if(${list_index} LESS 0)
LIST(APPEND dirlist ${LIB_NAME})
else()
endif()
endif()
endforeach()
set(${result} ${dirlist})
endmacro()
#调用函数,指定参数
#自动查找头文件路径函数
macro(FIND_UI_DIR result curdir) #定义函数,2个参数:存放结果result;指定路径curdir;
file(GLOB_RECURSE children "${curdir}/*.ui") #遍历获取{curdir}中*.hpp和*.h文件列表
file(GLOB SOURCE_UI ${children} ) #将文件放入 SOURCE_INCLUDE 中
set(dirlist "") #定义dirlist中间变量,并初始化
foreach(child ${children}) #for循环
string(REGEX REPLACE "(.*)/.*" "\\1" LIB_NAME ${child}) #字符串替换,用/前的字符替换/*h
if(IS_DIRECTORY ${LIB_NAME}) #判断是否为路径
list (FIND dirlist ${LIB_NAME} list_index) #判断dirlist是否含有${LIB_NAME}
if(${list_index} LESS 0)
LIST(APPEND dirlist ${LIB_NAME}) #将合法的路径加入dirlist变量中
else()
endif() #结束判断
endif()
endforeach() #结束for循环
set(${result} ${dirlist}) #dirlist结果放入result变量中
endmacro()
FIND_SRC_DIR(SRC_DIR_LIST ${PROJECT_SOURCE_DIR}/src)
FIND_INCLUDE_DIR(INCLUDE_DIR_LIST ${PROJECT_SOURCE_DIR}/src)
FIND_UI_DIR(UI_DIR_LIST ${PROJECT_SOURCE_DIR}/src)
#将INCLUDE_DIR_LIST中路径列表加入工程,包括第三方库的头文件路径
include_directories(
${INCLUDE_DIR_LIST} #INCLUDE_DIR_LIST路径列表加入工程
${PROJECT_SOURCE_DIR}/third_party/Boost/include/boost-1_81
)
#指定链接动态库文件夹
#增减windows库文件
if(WIN32)
set(PLAT_FROM_DEP
ws2_32.lib
)
endif()
#增加第三方连接库文件
file(GLOB LIB_Boost ${PROJECT_SOURCE_DIR}/third_party/Boost/lib/*.lib)
link_directories(${PROJECT_SOURCE_DIR}/third_party/Boost/lib)
# 指定格式为utf-8
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
#使用指定的源文件来生成目标可执行文件
add_executable(${PROJECT_NAME} main.cpp
${SOURCE_INCLUDE} ${SOURCE_SRC} ${SOURCE_UI} ${STDAFX_PCH_C})
target_link_libraries(${PROJECT_NAME} ${REQUIRED_LIBS_QUALIFIED})
target_link_libraries(${PROJECT_NAME} ${LIB_Boost})
if(WIN32)
target_link_libraries(${PROJECT_NAME} ${PLAT_FROM_DEP})
endif()
target_precompile_headers(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/protocol/stdafx.h)
main.cpp
#include <iostream>
#include <boost/signals2.hpp>
using namespace boost::signals2;
typedef signal<void(int, int)> vi_sig;
vi_sig sig2;
void slots1() {
std::cout << "slot 1 called" << std::endl;
}
void slots2(int a, int b, int c, int mm) {
std::cout << "slot 2 get a " << a
<< " get b " << b
<< " get c " << c
<< " get mm " << mm << std::endl;
}
void SetEventDataReceived(slot<void(int, int)> func)
{
sig2.connect(func);
}
int main() {
signal<void()>sig1;
sig1.connect(slots1);
sig1();
SetEventDataReceived( std::bind(slots2 , std::placeholders::_1, std::placeholders::_2, 3, 4) );
sig2(1, 2);
return 0;
}
上面的是一个不在类内的信号槽,因此我需要使用一个在类内的信号槽,把上面的代码稍作修改。
#include <iostream>
#include <boost/signals2.hpp>
using namespace boost::signals2;
typedef signal<void(int, int)> vi_sig;
vi_sig sig2;
class SlotTest
{
public:
static void slots2(int a, int b, int c, int mm) {
std::cout << "slot 2 get a " << a
<< " get b " << b
<< " get c " << c
<< " get mm " << mm << std::endl;
}
};
class SignalTest
{
public:
void Connect()
{
sig2(1, 2);
}
};
class SignalTest2
{
public:
void Connect()
{
sig2(1, 2);
}
};
int main()
{
// 只要在此处绑定了函数那么其他类只要执行该信号则会触发SLOT类的对应函数,则不需要关注调用者是谁
SlotTest aa;
sig2.connect(std::bind(aa.slots2 , std::placeholders::_1, std::placeholders::_2, 3, 4) );
SignalTest bb;
bb.Connect();
SignalTest2 cc;
cc.Connect();
return 0;
}
示例代码写的比较简单。如果需要写成项目的话还需要考虑更多的复杂情况,但是已经做到了解耦。
本文介绍了如何使用MSVC编译Boost库,特别是关注信号槽的使用。通过CMake配置项目,连接Boost库,并展示了不在类内的简单信号槽使用示例,以及如何将信号槽功能应用于类内部的方法。
1308

被折叠的 条评论
为什么被折叠?



