Взаимодействие с Windows API через Clozure CL

Я хочу вызвать функцию Windows API из Clozure CL через интерфейс внешних функций, но у меня возникли некоторые проблемы, потому что документации, которую я смог найти, довольно мало.

В качестве достаточно богатого примера я пытаюсь вызвать 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,
  • Определите структуру или класс FFI для хранения GUID (первый аргумент) через 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, до некоторой степени, когда я столкнулся с проблемой плохой поддержки Unisode CLisp в Windows (у меня был только первый символ пути, потому что CLisp читает строку UTF-16 как ASCII).

Дело в том, что я застрял в том, какие функции есть в CCL, чтобы заставить эту работу. Любая помощь в правильном направлении будет высоко ценится.

0 ответов

Другие вопросы по тегам