Windows需严格按OpenClipboard→EmptyClipboard→GlobalAlloc→GlobalLock→复制UTF-16→GlobalUnlock→SetClipboardData→CloseClipboard顺序操作;Linux推荐xclip或wl-copy;macOS须链接AppKit并处理隐私授权;跨平台优先用cpp-clipboard或SDL2。

Windows平台用OpenClipboard + SetClipboardData写入文本
Windows API 提供了直接操作剪贴板的底层能力,但必须严格按顺序调用,否则SetClipboardData会失败并返回NULL。常见错误是忘记清空旧内容、未分配全局内存、或在CloseClipboard前释放内存。
关键步骤:
- 调用
OpenClipboard(NULL)获取剪贴板所有权(失败则退出) - 调用
EmptyClipboard()清除当前内容(这步漏掉会导致写入失败) - 用
GlobalAlloc(GMEM_MOVEABLE, size)分配可移动全局内存,大小需包含结尾的\0 - 用
GlobalLock获取指针,复制UTF-16编码的字符串(Windows剪贴板文本要求CF_UNICODETEXT) - 调用
GlobalUnlock,再调用SetClipboardData(CF_UNICODETEXT, hMem) - 最后
CloseClipboard()释放所有权
注意:输入字符串如果是UTF-8,必须先转为UTF-16(可用MultiByteToWideChar(CP_UTF8, ...));直接传char*会导致乱码或崩溃。
Linux下用X11的XStoreBytes或xclip命令更可靠
X11协议本身不提供标准剪贴板API,原生C++调用XStoreBytes只能写入“服务器剪贴板”(PRIMARY),用户通常感知不到;真正对应Ctrl+C/V的是CLIPBOARD选择区,需手动实现选择区协议(含INCR、UTF8_STRING等原子协商),复杂度高且易出错。
立即学习“C++免费学习笔记(深入)”;
实操建议:
- 开发阶段直接调用外部工具:用
std::system("echo 'text' | xclip -selection clipboard -in -f")(需安装xclip) - 若坚持纯C++,推荐使用
libxcb封装库如xcb-util-xrm或更高层的gtk_clipboard_set_text(但会引入GTK依赖) -
xclip默认超时短,长文本可能失败,加-t 1000延长等待时间
注意:xclip在Wayland会失效,此时应改用wl-clipboard(命令为wl-copy)。
macOS用NSPasteboard需链接AppKit框架
macOS不允许后台进程随意访问剪贴板,必须链接AppKit且运行在主线程(或至少有NSApplication实例)。直接从控制台程序调用会静默失败——[NSPasteboard generalPasteboard]返回nil,但无错误提示。
正确做法:
- 项目需链接
-framework AppKit,CMake中加target_link_libraries(your_target "-framework AppKit") - 确保
NSApplicationLoad()已调用(CLI程序需手动触发) - 写入代码简洁:
[[NSPasteboard generalPasteboard] clearContents]; [[NSPasteboard generalPasteboard] setString:@"text" forType:NSPasteboardTypeString]; - 字符串自动处理编码,无需手动转UTF-16/UTF-8
注意:macOS 10.14+ 对后台程序剪贴板访问有隐私限制,首次运行会弹窗请求授权;若拒绝,后续调用不报错但无效。
跨平台方案别自己造轮子,用cpp-clipboard或SDL2
硬写三平台剪贴板逻辑极易遗漏细节:Windows内存管理、X11选择区状态同步、macOS权限弹窗时机。已有成熟轻量库能覆盖95%场景。
推荐选择:
-
cpp-clipboard(头文件仅clipboard.h):内部自动检测平台,Windows用API,Linux调xclip/wl-copy,macOS用NSPasteboard;支持UTF-8输入,自动处理编码转换 -
SDL2(若项目已用SDL):调SDL_SetClipboardText("text")即可,跨平台且无额外依赖,但需初始化SDL子系统(SDL_Init(SDL_INIT_VIDEO)) - 避免用
Qt的QClipboard:除非整个项目基于Qt,否则引入庞大依赖不划算
真实坑点:某些Linux发行版默认没装xclip或wl-copy,部署时需检查命令是否存在,否则cpp-clipboard会静默回退到失败状态,建议加一层which xclip校验。


















