从 Chibi Scheme FFI 绑定中的 out 参数获取 struct*
Get struct* from out parameter in Chibi Scheme FFI bindings
你能从 Chibi Scheme 的 C 函数的 out 参数中得到一个 struct *
吗?
我正在尝试从这个 C 函数中获取 struct archive_entry *
:
int archive_read_next_header(
struct archive *archive,
struct archive_entry **out_entry);
在 C 中,人们会这样做:
struct archive_entry *entry;
archive_read_next_header(archive, &entry);
我的 Chibi FFI 代码是:
(define-c-struct archive)
(define-c-struct archive_entry)
(define-c int
archive-read-next-header
(archive (result reference archive_entry)))
但是它没有生成正确的 C 代码来获取 archive_entry
。我
认为 reference
是错误的用法。我也试过pointer
但也没用。
还是不知道能不能直接做
但我能够通过在 C:
中编写自定义 thunk 函数来解决该问题
(c-declare "
struct archive_entry *my_archive_read(struct archive *a, int *out_errcode) {
struct archive_entry *entry;
int errcode;
*out_errcode = errcode = archive_read_next_header(a, &entry);
return (errcode == ARCHIVE_OK) ? entry : NULL;
}")
(define-c archive_entry my-archive-read (archive (result int)))
所以关键是Scheme在这个版本中不需要处理任何双向间接(**
)。 C 代码将 Scheme 的双间接寻址转换为单间接寻址,因此一切正常。
Scheme 程序的示例用法:
(let ((archive (my-archive-open filename)))
(disp "archive" archive)
(let* ((return-values (my-archive-read archive))
(entry (car return-values))
(errcode (cadr return-values)))
(display entry)
(newline)))
我从 chibi-sqlite3 绑定中复制了技术,他们面临类似的问题,必须从输出参数中获取 sqlite3_stmt *
:
(c-declare
"sqlite3_stmt* sqlite3_prepare_return(sqlite3* db, const char* sql, const int len) {
sqlite3_stmt* stmt;
char** err;
return sqlite3_prepare_v2(db, sql, len, &stmt, NULL) != SQLITE_OK ? NULL : stmt;
}
")
(define-c sqlite3_stmt (sqlite3-prepare "sqlite3_prepare_return") (sqlite3 string (value (string-length arg1) int)))
你能从 Chibi Scheme 的 C 函数的 out 参数中得到一个 struct *
吗?
我正在尝试从这个 C 函数中获取 struct archive_entry *
:
int archive_read_next_header(
struct archive *archive,
struct archive_entry **out_entry);
在 C 中,人们会这样做:
struct archive_entry *entry;
archive_read_next_header(archive, &entry);
我的 Chibi FFI 代码是:
(define-c-struct archive)
(define-c-struct archive_entry)
(define-c int
archive-read-next-header
(archive (result reference archive_entry)))
但是它没有生成正确的 C 代码来获取 archive_entry
。我
认为 reference
是错误的用法。我也试过pointer
但也没用。
还是不知道能不能直接做
但我能够通过在 C:
中编写自定义 thunk 函数来解决该问题(c-declare "
struct archive_entry *my_archive_read(struct archive *a, int *out_errcode) {
struct archive_entry *entry;
int errcode;
*out_errcode = errcode = archive_read_next_header(a, &entry);
return (errcode == ARCHIVE_OK) ? entry : NULL;
}")
(define-c archive_entry my-archive-read (archive (result int)))
所以关键是Scheme在这个版本中不需要处理任何双向间接(**
)。 C 代码将 Scheme 的双间接寻址转换为单间接寻址,因此一切正常。
Scheme 程序的示例用法:
(let ((archive (my-archive-open filename)))
(disp "archive" archive)
(let* ((return-values (my-archive-read archive))
(entry (car return-values))
(errcode (cadr return-values)))
(display entry)
(newline)))
我从 chibi-sqlite3 绑定中复制了技术,他们面临类似的问题,必须从输出参数中获取 sqlite3_stmt *
:
(c-declare
"sqlite3_stmt* sqlite3_prepare_return(sqlite3* db, const char* sql, const int len) {
sqlite3_stmt* stmt;
char** err;
return sqlite3_prepare_v2(db, sql, len, &stmt, NULL) != SQLITE_OK ? NULL : stmt;
}
")
(define-c sqlite3_stmt (sqlite3-prepare "sqlite3_prepare_return") (sqlite3 string (value (string-length arg1) int)))