我是Common Lisp的新手并做了一些实验。 我正努力获得对Windows剪贴板的一些访问权限,然后我找到了这个引用:
https://groups.google.com/forum/#!topic/comp.lang.lisp/hyNqn2QhUY0
这是完美的,除了它是为CLISP FFI量身定做的,我希望它与CFFI合作。 然后我尝试转换代码,并部分成功但是例程有问题 (get-clip-string),在WinXP(!)上使用Clozure CL 1.10进行测试:
测试文字:有太空服 - 将旅行
? (获得剪辑串)
错误:价值"有太空服 - 将旅行"不是预期的类型(UNSIGNED-BYTE 32)。 在进程监听器(1)中执行:GLOBAL-LOCK-STRING。 键入:要中止的POP,:R表示可用的重新启动列表。 类型:?其他选择。
我认为我没有在CFFI上找到类型的东西(虽然我已经阅读了手册),或CLISP上的原始处方。有人提示吗? 以下命令序列有效,但我担心这不安全:
app/helpers/application_helper.rb
(开放式剪辑0) (获取剪辑1) (close-clip 0)
这是代码:
(open-clip 0)
(get-clip 1)
(close-clip 0)
答案 0 :(得分:0)
错误在您用于GetClipboardData
的返回类型以及您用于GlobalLock
和GlobalUnlock
的参数类型中。您定义GetClipboardData
以返回字符串,但在C中,GetClipboardData
返回HANDLE
,其被定义为指向void
的指针,{{1}接受的参数}和GlobalLock
也是GlobalUnlock
。将C函数定义更改为:
HANDLE
......问题就消失了。
如果您想使用(cffi:defcfun ("GetClipboardData" get-clip) :pointer
(uformat :unsigned-int))
(cffi:defcfun ("GlobalLock" global-lock-string) :string
(type :pointer))
(cffi:defcfun ("GlobalUnlock" global-unlock) :int
(type :pointer))
,还需要修复其他global-lock-*
个功能以及memcpy
。
还有另一个错误:当您键入更正整个程序以便也可以调用set-clip-string
函数时,set-clip-string
似乎只能将字符串放到剪贴板上是Lisp进程的本地(我在Win7上通过SLIME使用SBCL的控制台构建)。假设您使用记事本将set-clip-string
复制到剪贴板。然后试试这个:
Have Space Suit-Will Travel
所以它似乎有效。但是如果你尝试使用 Shift Ins 从剪贴板粘贴到EMACS中,你会得到:
CL-USER> (set-clip-string "MY CLIPBOARD")
1
CL-USER> (get-clip-string)
"MY CLIPBOARD"
所以真实的剪贴板仍然有记事本放在那里,你的Lisp程序只有一个私人剪贴板,不能用于将数据复制到其他程序,甚至不是EMACS会话托管它。
这种情况正在发生,因为CL-USER> Have Space Suit-Will Travel
需要在致电set-clip-string
后致电empty-clip
。
此外,每个Windows调用都可能失败,但您的代码不会检查失败或处理错误。