通过Clozure CL与Windows API连接

时间:2015-08-11 12:11:56

标签: common-lisp ffi ccl

我想通过其外部函数接口从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>

获取/设置正确的方法签名

以下是我认为调用它的一般步骤,但我不确定每种方法如何:

  • 检索CCL为此功能生成的签名,以便我知道如何调用它。
  • 使用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的功能是什么。 我们非常感谢任何正确方向的帮助。

0 个答案:

没有答案