首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法获得在Gambit-C方案的FFI中工作的指针

无法获得在Gambit-C方案的FFI中工作的指针
EN

Stack Overflow用户
提问于 2013-03-02 03:08:15
回答 1查看 707关注 0票数 0

我正在用Gambit-C包装我的图形引擎API,到目前为止FFI已经成功了。今天我遇到了一个新的问题,我很难克服。

我在C中有这样的结构:

代码语言:javascript
复制
typedef struct render_list_rec
{
    long render_id;
    render_node* node;
    struct render_list_rec* next; 
} render_list;

在C中,我还有一系列由宏定义的函数来添加常见的列表行为。最后看起来是这样的:

代码语言:javascript
复制
void render_list_item_add(render_list_item **list, render_list_item* elem);

在C中,您可以有一个为NULL的render_list_item*,但是可以将它传递给这个函数的第一个参数,它实际上将为您创建列表的头。

我的问题是,我不能让这种行为在Gambit-C的FFI中工作。最后,我创建了这样的东西:

代码语言:javascript
复制
(c-define-type render-list* (pointer (struct "render_list_rec")))
(c-define-type render-list** (pointer (pointer (struct "render_list_rec"))))
(define render-list-add-item (c-lambda (render-list** long render-node*) render-list* "render_list_add_item"))

当我运行这个程序时,会出现分段故障。经调查,render-list-add-item过程的___arg1NULL。无论我尝试什么,都无法在FFI中获得有效的(指针(指针))。

有什么东西我错过了吗?

============================================================

一个完整的计划示例:

代码语言:javascript
复制
(c-declare #<<c-decl-end
#include <stdio.h>
#include <stdlib.h>

typedef struct test_rec
{
    int i;
} test_rec;

void pointer_test(struct test_rec** in_number)
{
  if (in_number == NULL) {
    fprintf(stdout, "pointer_test is NULL\n");
  }
}

test_rec* new_pointer_test(void)
{
return malloc(sizeof(struct test_rec));
}

c-decl-end
)

(c-define-type test-rec* (pointer (struct "test_rec")))
(define c-pointer-test (c-lambda ((pointer test-rec*)) void "pointer_test"))
(define c-new-pointer-test (c-lambda () test-rec* "new_pointer_test"))
(define test-rec->i-set! (c-lambda (test-rec* int) void "___arg1->i = ___arg2;"))

(display "About to run test with #f ...") (newline)
(define the_false #f)
(c-pointer-test the_false)

(display "About to run test with 1 ...") (newline)
(define number_one (c-new-pointer-test))
(test-rec->i-set! number_one 1)
(c-pointer-test number_one)

用下列方法汇编:

代码语言:javascript
复制
gsc -o test -exe  test.scm

给出输出:

代码语言:javascript
复制
About to run test with #f ...
pointer_test is NULL
About to run test with 1 ...
*** ERROR IN ##execute-program -- (Argument 1) Can't convert to C pointer
(c-pointer-test '#<|struct test_rec*| #2 0x28d3fc0>)

============================================================

编辑:

费利克斯:你能举几个例子来说明你是如何调用呈现列表添加项的吗?

用于此的C代码如下所示:

代码语言:javascript
复制
pg_render_list *ui_render_list = NULL;
pg_render_node *ui_node = pg_font_generate_text_string(app_font, L"Lacunarity:", ui_text_material);
pg_render_list_create_item(&ui_render_list, UI_ID_TEXT, ui_node);

它是基于沙利布的列表实现。当它们传递指向空指针的指针时,如上面所示,它将创建一个新的列表项作为列表的首项,这样*ui_render_list将指向它。

方案代码看起来如下(从内存中键入):

代码语言:javascript
复制
(define ui-render-list #f)
(letrec ((model-data (pg-model-data-read-binary model-filepath))
          (model-node (pg-render-node-create-fom-model model-data GL_STATIC_DRAW)))
  (pg-render-list-item-add ui-render-list model-data))

希望能有类似的行为。从文档中可以看出,catch中有一个#f转换为NULL,但我认为(指针(指针))可能会捕捉到这一点。即使传递绑定到某物的变量,也总是会导致空值。我通过在一个(c-声明)中创建一个简单地打印指针地址的函数来测试这一点:

如果您想查看我的完整包装器,可以使用看这里这份承诺

==========================================

如何使(指针(指针))工作的问题仍然存在。但是我认为为了更快的结果,以及更好的与其他语言的互操作性,我将重写我的C列表宏来定义一个列表结构,该结构将包含指向列表头/尾的指针,如“掌握C的算法”中所示。这样,指针指针就没有必要了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-05 13:02:33

也许我误解了,但当你

代码语言:javascript
复制
(define ui-render-list #f)

那么我就会认为这个短语:

代码语言:javascript
复制
(pg-render-list-item-add ui-render-list model-data)

会表现得像:

“使用实际参数#f和任何model-data表示的内容调用model-data

然后Gambit- C.将方案值#f转换为C值NULL (即0)。

这与以下各点有很大不同:

“用地址<addr>和任何model-data表示的东西调用<addr>”,其中<addr>pg-render-list-item-add创建的项目的接收者。

C声明:

代码语言:javascript
复制
pg_render_list_create_item(&ui_render_list, UI_ID_TEXT, ui_node);

获取ui_render_list变量的地址(例如,可以在堆栈上分配该地址),并将该地址传递给pg_render_list_create_item。这与将值NULL作为第一个参数传递给pg_render_list_create_item非常不同,该参数如下所示:

代码语言:javascript
复制
pg_render_list_create_item(ui_render_list, UI_ID_TEXT, ui_node);

注意没有符号和&;这是一个关键的区别。

我还没有花时间亲自用Gambit-C编写您的示例,但是我想,您可以通过自己分配接收内存(通过连接到FFI中的malloc函数)来实现您想要的效果,然后,一旦您分配了内存,您就有了一个地址,您可以将其作为第一个参数传递给pg-render-list-item

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15170249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档