将外部存储器解释为Lisp存储器(反之亦然),而不复制数据

MrC*_*Cat 5 common-lisp cffi

我尝试使用数据库API C函数(例如db-write-chunk)将BLOB逐块写入数据库。此函数将指向外部存储器(放置块)的指针作为参数。因此,我为块创建了缓冲区:foreign-buffer。我将采取从一个文件块的数据(或二进制流)read-sequencestream-buffer

(let ((foreign-buffer (foreign-alloc :uchar 1024)))
      (stream-buffer ((make-array 1024 :element-type '(unsigned-byte 8))))
    (loop
        for cnt = (read-sequence stream-buffer MY-STREAM)
        while (> cnt 0)
        do
          ;; copy cnt bytes from stream-buffer into foreign-buffer 
          ;; call db-write-chunk with foreign-buffer
Run Code Online (Sandbox Code Playgroud)

LBLOB中的“ Large”表示“大”,循环可能会迭代多次。除此之外,所有这些代码都可以由外部循环包装(例如,批量插入)。因此,我想最小化循环主体中的步骤数。

为此,我需要:

是否可以仅使用单个缓冲区(本机缓冲区或外部缓冲区)解决我的问题,而无需在它们之间复制内存?

小智 1

与其他 ffi 一样,这是依赖于实现的,但 cffi 有cffi:make-shareable-byte-vector,它是一个 CL(unsigned-byte 8)数组,然后您可以将其与 一起使用cffi:with-pointer-to-vector-data

(cffi:defcfun memset :pointer
  (ptr :pointer)
  (val :int)
  (size :int))

(let ((vec (cffi:make-shareable-byte-vector 256)))
  (cffi:with-pointer-to-vector-data (ptr vec)
    (memset ptr 0 (length vec))))
Run Code Online (Sandbox Code Playgroud)

根据您的使用情况,这可能比 更好static-vectors,因为您不必记住手动释放它。在 SBCL 上,这是通过在 期间固定矢量数据来实现的with-pointer-to-vector-data