您现在的位置是:网站首页> C/C++
C++第三方库&开源软件
- C/C++
- 2024-08-19
- 544人已阅读
C++第三方库&开源软件
SMFL游戏界面库
安装生成 C 和 C++ 应用所需的组件
CEF开源库
Windows 10 下使用Visual Studio 2017 编译CEF SDK
下载后的文件名如下所示:
cef_binary_3.2785.1466.g80e473e_windows32.tar.tar
cef_binary_3.2785.1466.g80e473e_windows64.tar.tar
可见:只有 Debug、Release、Resources 三个文件夹中的某些文件存在差异。所以,可将32位的Debug、Release、Resources重命名为Debug32、Release32、Resources32;64位的Debug、Release、Resources重命名为Debug64、Release64、Resources64。然后,将两个文件夹合并。
笔者将两个文件夹合并到了W:\libCEF\v3.2785.1466\unzip,其目录结构如下图所示
StdAfx.h
#define STR(x) #x
#define STR2(x) STR(x)
#define INCLUDE(f) STR2(PATH(f))
//包含 libCEF 的头文件
//下面的宏定义,##之前是 libCEF include 目录相对于本文件的相对路径
#define PATH(f) ../../libCEF/v3.2785.1466/unzip/include/##f
#define USING_CEF_SHARED 1
#include INCLUDE(cef_app.h)
#include INCLUDE(cef_client.h)
#undef PATH
#include "cefSimple.h"
//下面的宏定义是 libCEF 库文件相对于 vc 项目文件(*.vcproj/*.vcxproj)的相对路径
#define PATH "../../libCEF/v3.2785.1466/"
//连接库文件 libcef.lib
#ifdef _WIN64
#ifdef _DEBUG
#define PATH1 "unzip/Debug64/"
#else
#define PATH1 "unzip/Release64/"
#endif
#else
#ifdef _DEBUG
#define PATH1 "unzip/Debug32/"
#else
#define PATH1 "unzip/Release32/"
#endif
#endif
#pragma comment(lib,PATH PATH1 "libcef.lib")
#undef PATH1
//连接库文件 libcef_dll_wrapper.lib
#define PATH1 "libcef_dll_wrapper/bin/"
#if _MSC_VER==1500 //VC++9.0(VC2008)
#define PATH2 "vc2008"
#elif _MSC_VER==1600 //VC++10.0(VC2010)
#define PATH2 "vc2010"
#elif _MSC_VER==1700 //VC++11.0(VC2012)
#define PATH2 "vc2012"
#elif _MSC_VER==1800 //VC++12.0(VC2013)
#define PATH2 "vc2013"
#elif _MSC_VER==1900 //VC++14.0(VC2015)
#define PATH2 "vc2015"
#else
#error 未知的 VC++ 编译器
#endif
#ifdef _WIN64
#define PATH3 "-x64"
#else
#define PATH3 "-Win32"
#endif
#ifdef _DEBUG
#ifdef _UNICODE
#define PATH4 "-DU/"
#else
#define PATH4 "-DA/"
#endif
#else
#ifdef _UNICODE
#define PATH4 "-RU/"
#else
#define PATH4 "-RA/"
#endif
#endif
#ifdef _MT
#ifdef _DLL //使用多线程 DLL 版的 C 函数库
#define PATH5 "libcef_dll_wrapperD.lib"
#else //使用多线程版的 C 函数库
#define PATH5 "libcef_dll_wrapperT.lib"
#endif
#else //使用单线程版的 C 函数库
#define PATH5 "libcef_dll_wrapperS.lib"
#endif
#pragma comment(lib,PATH PATH1 PATH2 PATH3 PATH4 PATH5)
#undef PATH1
#undef PATH2
#undef PATH3
#undef PATH4
#undef PATH5
#undef PATH
#undef STR
#undef STR2
#undef INCLUDE
CWinApp
BOOL CmfcCEFApp::InitInstance()
{
CWinApp::InitInstance();
_tsetlocale(LC_ALL,_T(""));
{//CEF 初始化
CefMainArgs ma(m_hInstance);
CefRefPtr<SimpleApp> app(new SimpleApp());
int nCEP = CefExecuteProcess(ma,app.get(),NULL);
if(nCEP >= 0) { exit(nCEP); }
CefSettings settings;
CefString(&settings.locale) = L"zh-CN";
settings.no_sandbox = 1;
settings.multi_threaded_message_loop = 1;
CefInitialize(ma, settings, app.get(),NULL);
}
{
CmfcCEFDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
}
CefShutdown(); //退出 CEF
return FALSE;
}
Dialog
BOOL CmfcCEFDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CefWindowInfo wi;
RECT rc;
GetClientRect(&rc);
wi.SetAsChild(m_hWnd,rc);
CefBrowserSettings bs;
CefBrowserHost::CreateBrowser(wi,m_Handler.get()
,L"www.sina.com",bs,NULL);
return TRUE;
}
void CmfcCEFDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
HWND hWnd = m_Handler->m_hWndBrowser;
if(hWnd)
{
RECT rc;
GetClientRect(&rc);
::MoveWindow(hWnd,0,0,rc.right,rc.bottom,FALSE);
Invalidate();
}
}
编译mfcCEF成功后,先不要急着运行程序。因为mfcCEF.exe运行时需要一些文件,需要把它们复制到mfcCEF.exe所在目录。
假如mfcCEF.exe是32位的Release版,则
1、复制图1.3中Release32文件夹内的所有文件到mfcCEF.exe所在目录。注意:*.lib有259M,运行时不需要这些文件,所以就不用复制了。
2、复制图1.3中Resources32文件夹内的所有文件到mfcCEF.exe所在目录。
文件复制完成后,mfcCEF.exe所在目录如下图所示:
程序运行逻辑
运行mfcCEF,代码的执行顺序如下:
1、执行 CmfcCEFApp::InitInstance,调用 CefInitialize 初始化 CEF;
2、CmfcCEFApp::InitInstance 里的 dlg.DoModal() 显示程序主界面;
3、程序主界面被创建时,执行 CmfcCEFDlg::OnInitDialog,调用 CefBrowserHost::CreateBrowser 创建浏览器窗口;
4、浏览器窗口创建完毕后,执行 SimpleHandler::OnAfterCreated,获得浏览器窗口的句柄 m_hWndBrowser;
5、浏览器窗口是程序主界面窗口的子窗口。调整主界面大小时,将执行 CmfcCEFDlg::OnSize。OnSize 函数里移动浏览器窗口(句柄为 m_hWndBrowser)使其占满主界面窗口的客户区;
6、用户退出主界面,CmfcCEFApp::InitInstance 里的 dlg.DoModal() 将返回。同时对象 dlg 将被析构,其成员变量m_Handler 也将被析构。CefRefPtr<SimpleHandler> 使用了计数功能,m_Handler 析构时计数值减一后等于零,new SimpleHandler() 创建的对象将被自动 delete;
7、CmfcCEFApp::InitInstance 里的 CefShutdown() 被执行,退出 CEF;
8、CmfcCEFApp::InitInstance 返回 FALSE,整个程序不进入消息循环,而是结束。
下面说明一下对象new SimpleApp()的生命周期:
1、CefRefPtr<SimpleApp> app(new SimpleApp()) 后对象的计数值为 1;
2、CefInitialize(ma, settings, app.get(),NULL) 后对象的计数值为2;
3、app 析构后对象的计数值为 1;
4、CefShutdown() 后,app 的计数值为 0,对象自动被 delete。
mosquitto MQTT服务
客户端可用开放包
eclipse-paho-mqtt-c-win32-1.3.9.rar
mosquitto是一款开源的MQTT消息代理(服务器)软件,实现了MQTT协议版本3.1和3.1.1,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单,比如现在应用广泛的低功耗传感器,手机、嵌入式计算机、微型控制器等移动设备
Mosquitto项目还提供了用于实现MQTT客户端的C库以及非常受欢迎的mosquitto_pub和mosquitto_sub命令行MQTT客户端。
1)mosquitto:代理器主程序
2)mosquitto.conf:配置文件【路径:/etc/mosquitto】
3)mosquitto_passwd:用户密码管理工具
4)mosquitto_pub:用于发布消息的命令行客户端
5)mosquitto_sub:用于订阅消息的命令行客户端
6)mqtt:MQTT的后台进程
7)libmosquitto:客户端编译的库文件
关于连接认证、订阅认证和发布认证,Mosquitto 提供了多种机制来实现安全的 MQTT 通信:
1. 连接认证
用户名和密码:最基本的认证方式是通过客户端提供的用户名和密码进行认证。这需要在 Mosquitto 的配置文件中启用 password_file 选项,并使用 mosquitto_passwd 工具来创建和管理用户名和密码。
SSL/TLS:通过使用 SSL/TLS,可以在客户端和服务器之间建立加密的连接,同时也支持基于证书的客户端认证。这需要在配置文件中指定 cafile、certfile 和 keyfile 等选项。
2. 订阅认证和发布认证
访问控制列表(ACL):Mosquitto 允许使用访问控制列表(ACL)来限制客户端对特定主题的订阅和发布权限。ACL 规则可以在配置文件中指定,或者通过外部文件定义。每条规则指定了客户端或客户端组的订阅和发布权限。
插件:Mosquitto 支持使用插件扩展其功能,包括认证和授权。例如,mosquitto-auth-plug 插件支持多种后端存储(如 HTTP、JWT、MySQL、Redis 等),允许更灵活和强大的认证和授权机制。
实现示例
假设你想使用基于用户名和密码的认证,你需要进行以下步骤:
在 Mosquitto 的配置文件中启用密码文件:
password_file /path/to/passwordfile
使用 mosquitto_passwd 工具创建密码文件并添加用户:
mosquitto_passwd -c /path/to/passwordfile username
重启 Mosquitto 服务以应用更改。
对于更高级的认证和授权需求,你可能需要查阅 Mosquitto 的官方文档或考虑使用插件来实现。
password_file 用于 Mosquitto MQTT 代理中,存储用户名和密码信息,以便进行客户端连接认证。这个文件的内容包含了用户名和加密后的密码,每一行代表一个用户的凭证。请注意,为了安全性,密码在文件中是以加密形式存储的
johndoe:$6$+LRu4ZGJ$Y5M6Z...省略...k3R6FgH0
janedoe:$6$UMi9SDH$9aK8F...省略...3JUZP2C0
在这个示例中,johndoe 和 janedoe 是用户名,$6$+LRu4ZGJ$Y5M6Z...省略...k3R6FgH0 和 $6$UMi9SDH$9aK8F...省略...3JUZP2C0 分别是与这些用户名相关联的加密密码。
为了创建或更新这个文件,你需要使用 Mosquitto 提供的 mosquitto_passwd 工具。下面是一些基本的使用方法:
创建新的 password_file 并添加第一个用户:
mosquitto_passwd -c /path/to/passwordfile johndoe
这会提示你输入 johndoe 的密码两次来确认。
向已存在的 password_file 中添加新用户或更新现有用户的密码:
mosquitto_passwd /path/to/passwordfile janedoe
同样,这会提示你为 janedoe 输入密码两次。
请记住,每次修改 password_file 后,都需要重启 Mosquitto 服务或重新加载配置,以确保更改生效。
JS通过WebSockets访问mosquitto例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mosquitto WebSocket Example</title>
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
</head>
<body>
<script>
// 连接选项
const options = {
connectTimeout: 4000, // 超时时间
// 认证信息(如果需要)
clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
username: 'username', // 替换为你的用户名
password: 'password', // 替换为你的密码
};
// 使用 WebSocket 连接到代理
const client = mqtt.connect('ws://broker-address:9001', options);
client.on('connect', function () {
console.log('Connected to Mosquitto via WebSocket!');
// 连接成功后订阅主题
client.subscribe('test/topic', function (err) {
if (!err) {
// 订阅成功后发布消息
client.publish('test/topic', 'Hello MQTT over WebSocket!');
}
});
});
// 接收消息
client.on('message', function (topic, message) {
// message 是一个 Buffer
console.log(message.toString());
// 关闭客户端
client.end();
});
// 监听错误事件
client.on('error', function (error) {
console.log('Connection failed:', error);
});
</script>
</body>
</html>
Serial-Studio一个开源串口神器
一个开源的串口项目——Serial Studio,这是一个强大的数据可视化软件,支持串口通信,串口终端,网络通信 TCP/UDP,MQTT通信协议。这个项目遵循MIT协议,所以是可以商用的。
IM开源即时通讯软件
一、FlamingoIM
FlamingoIM 是一款轻量级开源即时通讯软件,其目前有服务器端、pc 端和安卓端,三端都是 native 应用,从通信协议到界面库都自主开发,不是使用第三的库包装而成。大家平常用微信和 QQ 比较多,所以学习起来,对即时通讯本身没有业务理解负担。
https://github.com/balloonwj/flamingo
开发语言:
Server:C++
PC:C++
Android:Java
IOS:Objective-C
二、TeamTalk
TeamTalk 简称 tt,是蘑菇街开源的一款即时通讯 IM,代码地址:
https://github.com/balloonwj/TeamTalk
开发语言:
Server:C++
PC:C++
Android:Java
IOS:Objective-C
Web 管理:php