Windows 平台 C++ 开发实战
·
Windows 平台 C++ 开发实战
简介
在 Windows 平台上进行 C++ 开发,需要掌握许多平台特定的知识和技巧。本文聚焦于 Windows 平台开发的核心主题,包括 DLL 与静态库的制作与调试、Windows 服务编程、内存泄漏检测,以及 Bloom 过滤器等实用工具类。这些内容在实际项目开发中具有很高的实用价值。
一、DLL与静态库制作
1.1 Windows 下制作 DLL(VS2017)
- 新建项目 -> Visual C++ -> Windows桌面 -> 动态链接库
- 在要导出的类或函数加上
__declspec(dllexport) - 导入时使用
__declspec(dllimport) - 生成的
.lib文件是导入库(符号表),不是静态库
// 导出
class __declspec(dllexport) MyClass {
// ...
};
// 导入
class __declspec(dllimport) MyClass {
// ...
};
1.2 Windows 下制作静态库
- 新建项目 -> 静态库
- 在需导出的函数或类加上
extern声明 - 生成
.lib文件
1.3 Linux 下制作动态库
g++ -fPIC -c source.cpp # 生成 .o 文件
g++ -shared -o libname.so source.o # 生成动态库
# 或者合并为一步
g++ -fPIC -shared -o libname.so source.cpp
1.4 Linux 下制作静态库
ar -crv libname.a source1.o source2.o
1.5 VS 跨平台编译 Linux 动态库
- 属性 -> 常规 -> 目标文件名:改为
lib$(ProjectName) - 属性 -> 常规 -> 目标扩展名:改为
.so - 属性 -> C/C++ -> 附加选项:添加
-fPIC - 属性 -> 链接器 -> 附加选项:添加
-shared
1.6 调试 DLL
在 Windows 下调试 DLL 代码时,需要将生成 DLL 工程的 .pdb、.lib 和 .dll 文件拷贝至当前工程的 Debug 目录下。
1.7 在 C++ 中调用 C 编写的库
// 必须在头文件中添加 extern "C"
extern "C" {
#include "c_library.h"
}
否则由于 C++ 的名称修饰(name mangling),链接器无法找到正确的符号。
二、Windows 服务编程
#include <Windows.h>
HANDLE hSvcStopEvent = nullptr;
SERVICE_STATUS serviceParam;
SERVICE_STATUS_HANDLE serviceHandle;
static char name[64]{ "ClearService" };
void WINAPI CtrlHandler(DWORD request) {
switch (request) {
case SERVICE_CONTROL_STOP:
SetEvent(hSvcStopEvent);
serviceParam.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(serviceHandle, &serviceParam);
break;
case SERVICE_CONTROL_SHUTDOWN:
serviceParam.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(serviceHandle, &serviceParam);
SetEvent(hSvcStopEvent);
break;
}
}
void WINAPI ServiceMain(int argc, char** argv) {
// 初始化服务...
hSvcStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
serviceParam.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(serviceHandle, &serviceParam);
// 自定义服务入口
// ...
WaitForSingleObject(hSvcStopEvent, INFINITE); // 等待停止信号
}
int main(int argc, char* argv[]) {
SERVICE_TABLE_ENTRY entrytable[2];
entrytable[0].lpServiceName = name;
entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
entrytable[1].lpServiceName = nullptr;
entrytable[1].lpServiceProc = nullptr;
StartServiceCtrlDispatcher(entrytable);
return 0;
}
三、内存泄漏检测
3.1 Visual C++ 内存泄漏检测(crtdbg.h)
#define _CRTDBG_MAP_ALLOC // 用于定位产生内存泄漏的文件和行号
#include <crtdbg.h>
int main() {
// 方法1:在程序退出前调用
_CrtDumpMemoryLeaks();
// 方法2:自动检测(多个退出点时使用)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
// 方法3:在指定编号处断点
_CrtSetBreakAlloc(96); // 在编号96的内存分配处断点
}
输出示例:
Dumping objects ->
{96} normal block at 0x006B9090, 20 bytes long.
Data: < > 00 00 00 00 ...
Object dump complete.
3.2 广义内存泄漏
不仅包含堆内存泄漏,还包括系统资源泄漏:
- 内核态 HANDLE
- GDI Object
- SOCKET
- Interface 等
系统资源泄漏可能比堆内存泄漏更严重,因为核心态内存泄漏会导致操作系统不稳定。
四、Bloom 过滤器
Bloom 过滤器用于快速判断某个 key 是否可能存在:
// 本质是一个 bitset
// 插入:将 key 通过多个哈希函数映射到多个 bit 位,置为 1
// 查询:检查所有映射的 bit 位是否都为 1
// - 全为 1:key 可能存在(可能有碰撞)
// - 不全为 1:key 一定不存在
// 优化碰撞:
// 1. 增大 bits_per_key
// 2. 使用更复杂的哈希函数
// 参考:leveldb/util/bloom_test.cc
总结
Windows 平台 C++ 开发涉及许多平台特有的工具和 API。掌握 DLL/静态库的制作与调试是跨平台开发的基础,Windows 服务编程是后台服务开发的核心技能,内存泄漏检测则是保障软件质量的关键手段。
关键实战要点:
- 熟练制作和使用 DLL 与静态库,理解导入库与静态库的区别
- 掌握 Windows 服务编程模型(ServiceMain + CtrlHandler)
- 使用 crtdbg.h 等工具定位和修复内存泄漏
- 关注广义内存泄漏(HANDLE、GDI、SOCKET 等系统资源)
- 了解 Bloom 过滤器等实用数据结构的应用场景
原始笔记来源: hhjt/c++11learn.cpp
更多推荐



所有评论(0)