windows用openclipboard+setclipboarddata写入文本需调用win32 api,核心是分配gmem_moveable内存、globallock写入utf-16字符串、设cf_unicodetext格式;linux推荐xclip命令,macos用pbcopy或nspasteboard(需objective-c++)。

Windows平台用OpenClipboard + SetClipboardData写入文本
在Windows上,C++没有标准库支持剪贴板操作,必须调用Win32 API。核心流程是:打开剪贴板 → 分配全局内存 → 复制字符串到该内存 → 设置CF_UNICODETEXT格式数据 → 关闭剪贴板。
常见错误是忘记调用GlobalLock和GlobalUnlock,或传入ANSI字符串却声明为CF_UNICODETEXT,导致粘贴时乱码或失败。
实操要点:
-
OpenClipboard必须传入NULL(不能传窗口句柄,除非你真在处理UI线程且有HWND) - 分配内存用
GlobalAlloc(GMEM_MOVEABLE, size),size按字节算:UTF-16长度 × 2 + 2(结尾\0) - 写入前务必
GlobalLock拿到指针,写完立刻GlobalUnlock,但不要free它——系统接管所有权 - 调用
SetClipboardData(CF_UNICODETEXT, hMem)后,即使失败也不用GlobalFree,成功则系统会管理释放
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, (wcslen(text) + 1) * sizeof(wchar_t));
if (hMem) {
wchar_t* p = static_cast<wchar_t>(GlobalLock(hMem));
if (p) {
wcscpy_s(p, wcslen(text) + 1, text);
GlobalUnlock(hMem);
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, hMem);
}
}</wchar_t>
Linux下用X11的XStoreBytes或更可靠的xclip命令
X11协议本身不提供“剪贴板”抽象,而是靠PRIMARY、CLIPBOARD两个选择(selection)机制。直接用Xlib写非常繁琐,容易卡死(比如没正确处理事件循环或所有权竞争)。
实际项目中更推荐绕过Xlib,用xclip命令行工具——它稳定、支持UTF-8、自动处理selection协商。
实操建议:
- 确保系统已安装:
sudo apt install xclip(Debian/Ubuntu)或sudo yum install xclip(RHEL/CentOS) - 用
popen调用:"xclip -selection clipboard -in -t text/plain",然后fwrite字符串并fclose - 别用
system(),它无法捕获错误;也别漏掉-t text/plain,否则中文可能被识别为UTF8_STRING但粘贴端不兼容 - 注意:Wayland会话下
xclip可能无效,需换用wl-copy(sudo apt install wl-clipboard)
macOS用NSPasteboard需要Objective-C++混编
C++原生无法调用AppKit,必须启用Objective-C++(文件后缀改为.mm),并在编译时链接-framework AppKit。
关键点在于:不能直接传C++ std::string,必须转成NSString*;且NSPasteboard默认只接受NSStringPboardType,不支持原始字节流。
实操注意:
- 获取pasteboard用
[NSPasteboard generalPasteboard],不是copyPasteboard - 写入前先
clearContents,再setData:forType:,类型必须是NSStringPboardType - UTF-8字符串转
NSString*用[[NSString stringWithUTF8String:cstr],空指针会崩溃,务必判空 - 如果工程纯C++,不希望引入ObjC,可改用命令行
pbcopy:echo "text" | pbcopy,用popen执行
跨平台方案别自己封装,优先用clip crate(Rust)或Python子进程
纯C++跨平台剪贴板库(如cpp-clip)维护差、Unicode支持残缺、Linux下依赖未明确定义。真实项目里,与其花三天调试X11 selection时序,不如用脚本桥接。
最省心的路径:
- 用Python写个极简脚本:
import pyperclip; pyperclip.copy(sys.argv[1]),C++用popen("python3 clip.py 'hello'") - 或者直接依赖现成CLI工具:Windows用
Set-Clipboard(PowerShell),Linux用xclip/wl-copy,macOS用pbcopy,统一用popen调用 - 注意路径问题:
xclip可能不在/usr/bin,建议用which xclip查位置,或让用户配置PATH - 别忽略编码:所有输入字符串必须是UTF-8(Linux/macOS)或UTF-16(Windows),混用
std::string和本地编码极易出错
真正麻烦的从来不是API调用,而是字符编码上下文切换——Windows API要宽字符,X11工具吃UTF-8,macOS命令行又认locale。把编码转换逻辑单独抽成函数,比反复检查SetClipboardData返回值重要得多。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











