gpt4 book ai didi

Racket FFI 中 cstructs 的折叠偏移量

转载 作者:太空宇宙 更新时间:2023-11-03 23:19:37 25 4
gpt4 key购买 nike

我有一个很大的结构,中间有两个字段描述列表大小和指向列表的指针:

(define-cstruct _context
(...
[size _uint]
[lst _pointer]
...)

然而,要获得这个列表,我总是首先需要获取大小,然后将指针转换为给定大小的列表。显然我可以创建一个函数来执行此操作:

(define (convert-to-list size clst)
...)

但我认为我们可以做得更好。也就是说,我想让该字段“感觉”成一个 Racket 列表/vector ,而不必不断地将它传递给 convert-to-list。我们可以用另一个 define-cstruct 完成大部分工作,假设我们这样做:

(define _clist
(let ()
(define-cstruct _clist
([size _uint]
[lst _pointer])
(make-ctype _clist #f
(lambda (v)
(cblock->list (ptr-ref (clist-lst v) _pointer)
_pointer
(clist-count v))))))

现在我可以将这个新结构放回旧结构中:

(define-cstruct _context
(...
[lst _clist]
...))

问题是 _clist 现在读取的是 C 数据类型,这意味着它尝试为这个新结构使用标准 C 偏移量,而不是“内联”数据,可以这么说。

有什么方法可以让 Racket 使用填充来使用这种模式,就好像新结构是直接用外部结构编写的一样?

(显然我可以使用 Racket 的元编程来内联结构,但那是使用核选项,如果我不需要它我想避免。)

最佳答案

是的,实际上有一种方法可以通过在define-cstruct .

只需给内部结构 #:alignment 1,它就会自行对齐,没有额外的填充。

您的结果代码应如下所示:

(define _clist
(let ()
(define-cstruct _clist
([size _uint]
[lst _pointer]
#:alignment 1)
(make-ctype _clist #f
(lambda (v)
(cblock->list (ptr-ref (clist-lst v) _pointer)
_pointer
(clist-count v))))))

现在您可以在外部结构中使用您的新结构,就好像直接提供了一个具有长度的列表一样:

(define-cstruct _context
(...
[lst _clist]
...))

感谢 Matthew Flatt 帮助我得出这个答案。

关于Racket FFI 中 cstructs 的折叠偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44229845/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com