我一直在研究Practical Common Lisp的二进制解析器项目,并试图将泛型(类和宏定义)和细节(特定类型和方法实现)拆分到不同的包中。因此,我有以下代码:
在 packages.lisp 中:
(defpackage :binparse
(:use :cl)
(:export :read-value :write-value :read-object :write-object
:current-binary-object :parent-of-type :define-binary-class
:define-tagged-binary-class :define-binary-type))
(defpackage :primitives
(:use :cl :binparse))
在 binparse.lisp 中:
(defgeneric read-value (type stream &key)
(:documentation "Read a value of the given type from the stream."))
(defgeneric write-value (type stream value &key)
(:documentation "Write the value of the given type to the stream."))
(defmacro define-binary-type (name (&rest args) &body spec) ...) ; calls defmethod for read-value and write-value, specialized on (type (eql ,name))
在primitives.lisp中:
(define-binary-type u1 () ...) ; defines reader and writer spec for 1-byte unsigned int, specialized on (type (eql 'u1))
我一直无法确定如何正确地从primitives
. 如果我不做任何超出packages
上面定义的导出,那么我可以执行以下操作:
CL-USER> (binparse:read-value primitives::'u1 *testfile*) ; succeeds
CL-USER> (binparse:read-value primitives::u1 *testfile*) ; fails, unbound variable U1
CL-USER> (binparse:read-value 'u1 *testfile*); fails, class-not-found u1
PRIMITIVES> (read-value 'u1 *testfile*) ; succeeds
但是,我不知道如何导出'u1
(或用作方法说明符的其他符号)primitives
以避免双冒号或可能允许导入其他包。包括(:export :u1)
在defpackage
不起作用。(export 'u1)
已经在 中时也不会调用primitives
。与双冒号不同,单冒号不允许::'u1
原来的工作。
从PCL扩展项目,这似乎是一件相当正常的事情,在一个包中定义基本的二进制解析器代码,以便在其他地方用于特定的扩展,但我不知道该怎么做并且没有没有找到其他人询问它。