1

我一直在研究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扩展项目,这似乎是一件相当正常的事情,在一个包中定义基本的二进制解析器代码,以便在其他地方用于特定的扩展,但我不知道该怎么做并且没有没有找到其他人询问它。

4

1 回答 1

3

想通了:如果我(:export #:u1)在 中packages.lisp,我可以使用(binparse:read-value 'primitives:u1 *testfile*). 因此,引号位于符号的包名部分之前。

于 2020-10-15T21:30:17.567 回答