首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CLISP FFI外国价值问题

CLISP FFI外国价值问题
EN

Stack Overflow用户
提问于 2014-02-19 01:00:40
回答 1查看 258关注 0票数 1

我试图使用CLISP调用一些Win32函数。

我能够发出一个调用,并在Lisp中调用一个回调,但现在我不知道如何访问传递给回调的值。

其中一个值是指向struct的指针。我已经定义了这个结构,我可以打印它,得到一个#<FOREIGN-VARIABLE #x00000000>,或者把它包装在foreign-address中,然后得到#<FOREIGN-ADDRESS #x00000000> (这两者都不是真正的值或加载项),但是当我尝试对它进行deref时,我会得到以下内容:

代码语言:javascript
复制
*** - FFI:DEREF is only allowed after FFI:FOREIGN-VALUE:
  (FFI:DEREF (FFI:FOREIGN-ADDRESS PRECT*))

我尝试过将foreign-address调用包装在foreign-value中,尝试使用with-c-place和其他东西,但是没有任何效果。我要么没有打印任何内容(在这种情况下,假设调用过程中出现了错误并对其进行了编码),要么我得到了该错误。

我找到的唯一文档是这个dffi引用,但是它没有足够的例子,这些函数的文档也不清楚。

有人有指点吗?(双关语)我应该切换到CFFI/UFFI还是SBCL?

更新

在将指针包装在REPL中的foreign-value reload中(没有退出)之后,我让它打印了一次结构,然后它似乎在后面的reloads的回调中出错。

编辑

仍然无法让它工作;下面是代码:

代码语言:javascript
复制
(defpackage "WIN32")
(in-package "WIN32")
(use-package "FFI")

; Listen for a WM_DISPLAYCHANGE message to get notifications of when
; a monitor (setting) is added/removed/changed



(def-c-type BOOL     boolean)
(def-c-type CHAR     char)
(def-c-type DWORD    uint)
(def-c-type HANDLE   c-pointer)
(def-c-type HDC      HANDLE)
(def-c-type HMONITOR HANDLE)
(def-c-type HWND     HANDLE)
(def-c-type LONG     long)
(def-c-type LPARAM   c-pointer)
(def-c-type LPCSTR   c-string)
(def-c-type LPCTSTR  LPCSTR) ; LPCWSTR
;(def-c-type LPCWSTR  )
(def-c-type TCHAR    CHAR) ; WCHAR
;(def-c-type WCHAR    )


(defun symbol-to-keyword (sym)
  (intern (symbol-name sym) :keyword))


(defun affix-to-symbol (prefix sym suffix)
  (intern (concatenate 'string prefix (symbol-name sym) suffix)))


(defun car-symbol-to-keyword (pair)
  (cons
    (symbol-to-keyword (car pair))
    (cdr pair)))



(defmacro def-struct-type (name &rest fields)
  `(progn
    (def-c-struct ,name ,@fields)
    (def-c-type
      ,(affix-to-symbol "P" name "")
      (c-pointer ,name))
    (defconstant
      ,(affix-to-symbol "" name "-INSTANCE")
      '(c-struct ,name ,@(mapcar #'car-symbol-to-keyword fields)))
    ))


;typedef struct _RECT {
;  LONG left;
;  LONG top;
;  LONG right;
;  LONG bottom;
;} RECT, *PRECT;

(def-struct-type RECT
  (left   LONG)
  (top    LONG)
  (right  LONG)
  (bottom LONG))


;BOOL CALLBACK MonitorEnumProc(
;  _In_  HMONITOR hMonitor,
;  _In_  HDC hdcMonitor,
;  _In_  LPRECT lprcMonitor,
;  _In_  LPARAM dwData
;);

;BOOL EnumDisplayMonitors(
;  _In_  HDC hdc,
;  _In_  LPCRECT lprcClip,
;  _In_  MONITORENUMPROC lpfnEnum,
;  _In_  LPARAM dwData
;);


(def-call-out EnumDisplayMonitors
  (:name "EnumDisplayMonitors")
  (:library "User32.dll")
  (:arguments
    (hdc      HDC)
    (lprcClip PRECT)
    (lpfnEnum 
      (c-function
        (:arguments
          (hMonitor    HMONITOR)
          (hdcMonitor  HDC)
          (lprcMonitor PRECT)
          (dwData      LPARAM))
        (:return-type BOOL)
        (:language :stdc-stdcall)))
    (dwData   LPARAM))
  (:return-type BOOL)
  (:language :stdc-stdcall))
(export 'EnumDisplayMonitors)


(defun callback (hmon hdc* prect* data)
  (progn
    (format t "~A ~A ~A ~A~%" hmon hdc* (foreign-address prect*) data)
    t))

(EnumDisplayMonitors nil nil #'callback nil)
EN

回答 1

Stack Overflow用户

发布于 2014-03-10 15:30:32

使用slotc-var-object

slotc-var-object

更多的例子

中可以找到更多示例。

  • 试验/检验
  • 模块/绑定/glibc/tests.tst模块/绑定/glibc/linux.lisp
  • 模块/绑定/win32 32/tests.tst模块/绑定/win32 32/win32.lisp
  • 模块/dbus/tests.tst模块/dbus/dbus.lisp
  • 更多的ffi模块

未来

实际上,现在sbcl比clisp维护得更好,所以您可能需要考虑切换。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21868843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档