我想定义一个封装下面频繁模式的宏。 该代码适用于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)的琴弦位于琴身中间, 我不得不将身体分成两部分: 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)))))
答案 0 :(得分:2)
只想分享我改变了宏,如下所示:
(defmacro with-foreign-str (strs str-syms bdy)
(if (null strs)
bdy
`(let ((,(car str-syms) (gensym)))
(fli:with-foreign-string
(,(car str-syms) ec bc :external-format (external-format)) ,(car strs)
(with-foreign-str ,(cdr strs) ,(cdr str-syms) ,bdy)))))
然后不使用宏的上面的代码可以像这样重写:
(WITH-FOREIGN-STR ("BUTTON" "Configuartion: server") (cn-p wn-p)
(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)))
(WITH-FOREIGN-STR ("EDIT" "192.168.200.95") (cn-p3 wn-p3)
(createwindowex 0 cn-p3 wn-p3
(logior ws_visible ws_child ws_border)
10 30 150 30 hwnd 1 (GetModuleHandle-current 0) 0))))
这仍然不是那么干净但无论如何我可以设法使用宏来简化代码。 没有那么多的回复只是因为我认为由于代码中的FLI和win32 API。