我想通过其外部函数接口从Clozure CL调用Windows API函数,但我遇到了一些问题,因为我能找到的文档相当稀少。
作为一个足够丰富的例子,我试图打电话给SHGetKnownFolderPath。 它的签名是
HRESULT SHGetKnownFolderPath(const GUID &rfid, DWORD dwFlags,
HANDLE hToken, PWSTR *ppszPath );
我可以使用以下内容来获取函数的入口点:
(open-shared-library "shell32.dll")
> #<SHLIB SHELL32.dll #x1234>
(external "SHGetKnownFolderPath")
> #<EXTERNAL-ENTRY-POINT "SHGetKnownFolderPath" (#x12345) SHELL32.dll #x123456>
以下是我认为调用它的一般步骤,但我不确定每种方法如何:
external-call
为其提供不同的功能签名。GUID
或相关构造定义FFI结构或类以保存def-foreign-type
(第一个参数)。CoTaskMemFree
释放*ppszPath
指向的内存。我对最终代码采用的一般形式的猜测是
(defun get-known-folder (guid)
(let ((ffi-guid (allocate-ffi-memory-from-guid guid))
(ffi-path ffi-version-of-nil)
(path nil))
(external-call "SHGetKnownFolderPath" ...) ;; Pass ffi-guid and ffi-path by reference.
(setf path (convert-cstring-to-string ffi-path))
(external-call "CoTaskMemFree" ...) ;; Free ffi-path.
path))
仍有各种未知函数和函数调用在C / FFI和Lisp之间进行转换。
我非常熟悉Windows API并完成了其他语言的Win32 API调用。我还设法让它在CLisp中工作,直到某一点,因为我遇到了Windows中对CLisp的不良Unicode支持的问题(我最终只得到了路径的第一个字符,因为CLisp读取了UTF-16字符串as ASCII)。
我坚持的观点是CCL的功能是什么。 我们非常感谢任何正确方向的帮助。