我想定义一个宏来封装下面的频繁模式。该代码适用于 lispworks 的 FLI。
(fli:with-foreign-string ;; class name pointer
(cn-p ec bc :external-format (external-format)) "BUTTON"
(fli:with-foreign-string ;; window name pointer
(wn-p ec bc :external-format (external-format)) "Configuartion:server"
(let ((grpbx (createwindowex 0 cn-p wn-p
(logior ws_visible ws_child bs_groupbox)
0 0 300 420 hwnd 1 (GetModuleHandle-current 0) 0)))
(fli:with-foreign-string ;; class name pointer
(cn-p ec bc :external-format (external-format)) "EDIT"
(fli:with-foreign-string ;; window name pointer
(wn-p ec bc :external-format (external-format)) "192.168.200.200"
(createwindowex 0 cn-p wn-p
(logior ws_visible ws_child ws_border)
10 30 150 30 hwnd 1 (GetModuleHandle-current 0) 0)
)))))
我要创建的宏如下所示:strs参数是字符串列表,例如上面的("BUTTON" "Configuartion:server"), str-syms会累积转换后的字符串,这些字符串将被馈送到createwindowex。让我困惑的是要使用的字符串(cn-p 和 wn-p)在 body 的中间,我不得不将 body 分成 2 部分:part-bdy和&body bdy。
但问题是part-bdy,它是LET块的第一部分(在createwindowex之前),有很多括号,其对应部分仅在发送部分(&body bdy)。这意味着part-bdy中的括号未打开并在评估时导致错误。你有什么聪明的主意可以建议我解决吗?
(defmacro with-foreign-string (strs str-syms part-bdy &body bdy)
(let ((g (gensym)))
(if (null strs)
(append part-bdy str-syms bdy)
`(fli:with-foreign-string
(,g ec bc :external-format (external-format)) ,(car strs)
(with-foreign-string ,(cdr strs) ,(cons g str-syms) ,part-bdy ,@bdy)))))