我正在写一个程序/游戏,我使用Guile在C程序上编写脚本。例如,我在C中有一个命令结构类型(也用于move_to)和相应的move_to
Package 函数,以在Guile中创建move_to命令。在UI中,可以输入一行输入,然后在Guile中执行。
对于move_to
,它在C语言中如下所示:一些实体id在这里作为SCM值传递,对于新的位置也是如此,SCM值传递给x,传递给y。
static SCM move_to(SCM scm_id, SCM x, SCM y) {
unsigned int id = scm_to_int(scm_id);
float new_x = scm_to_double(x);
float new_y = scm_to_double(y);
// Search for entity
int index = -1;
for (int i = 0; i < gs.entities.size(); i++) {
if (get_id(&(gs.entities[i])) == id) { index = i; break; }
}
command c = {new_x,new_y,MOVETO,0};
// Add move command to entity if one was found
if (index != -1) { printf("found index\n");add_command(&(gs.entities[index]), c); }
return SCM_UNSPECIFIED;
}
在这段代码中,实体在实体列表中搜索,如果存在,我们创建一个新的move_to_command
并将其添加到实体的命令列表中。
在UI中,可以输入(move_to 0 100 100)
,然后执行。
当函数只返回一个整数或者什么都不返回时,创建一个C函数和 Package 器是很简单的,但是我不确定如何实现一个向Guile返回(C -/Guile-)结构值的函数。
假设我们在C语言中有这样的结构类型:
typedef struct {
unsigned int id;
event_type type;
unsigned int entity_id;
unsigned int by_entity;
} event;
我如何从这个C结构体创建一个Guile结构体值,这个C结构体值是在调用一些Guile函数时返回的,比如'get-next-event'
(我必须写),现在如果我必须把这个值从C结构体复制到一个新的Guile结构体中,也是可以的。
看到有函数scm_make_struct(SCM vtable, SCM tail_size, SCM init_list)
,但我不知道如何创建一个vtable值,将其作为第一个参数传递到这里。
我认为旧的guile版本是scm_make_vtable_vtable
。我也尝试了当前版本的C函数scm_struct_vtable
。
附录:
- 在文件struct. h中找到一个创建vtable的函数,但未记录:
SCM_API SCM scm_make_vtable (SCM fields, SCM printer);
源代码示例:
#include "libguile.h"
static SCM give_me_100(void) {
return scm_from_int(100);
}
static SCM give_me_a_struct(void) {
SCM fields = scm_from_locale_string("pwpw");
SCM vtable = scm_make_vtable(fields,0);
SCM mystruct = scm_c_make_struct(vtable,0, 10, 20, SCM_UNDEFINED); //
return mystruct;
}
static void inner_main(void *closure, int argc, char **argv) {
/* preparation - make C functions callable from Guile */
scm_c_define_gsubr("give-me-100", 0, 0, 0, &give_me_100);
scm_c_define_gsubr("give-me-a-struct", 0, 0, 0, &give_me_a_struct);
scm_shell(argc, argv);
/* after exit */
}
int main(int argc, char **argv) {
scm_boot_guile(argc, argv, inner_main, 0);
return 0; /* never reached, see inner_main */
}
例如,可以使用以下代码行进行编译:gcc-o主文件-I/用户名/包含/文件夹/3.0-文件夹-3.0主文件. c
输出示例:
GNU Guile 3.0.8
Copyright (C) 1995-2021 Free Software Foundation, Inc.
Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.
Enter `,help' for help.
scheme@(guile-user)> (give-me-100)
$1 = 100
scheme@(guile-user)> (give-me-a-struct)
$2 = zsh: segmentation fault (core dumped) ./main
谢谢你的任何帮助和建议,雷尔
1条答案
按热度按时间5tmbdcev1#
要使用C结构体并将其导出到Guile,可以这样做-示例代码来自以下内容:https://github.com/agentlans/guile-foreign-example/blob/master/bessel.c