2

我正在探索为 D 语言 ( http://d-programming-language.org/ ) 创建 Clutter 绑定的可能性,并开始尝试使用动态加载 libclutter 进行一些简单的测试。我遇到了一个可能源自 GObject 继承系统的问题,如果能帮助我解决这个问题,我将不胜感激。这是概要:使用 clutter_stage_get_default 返回一个 ClutterActor*,我可以将其与 clutter_actor_* 方法一起使用。但是当我使用 clutter_stage_* 或 clutter_container_* 方法时,我总是会遇到错误或段错误。这是我的测试代码: http: //pastebin.com/nVrQ69dU

在第 56 行的 clutter_container_add_actor 调用中,我收到以下错误: (<unknown>:11976): Clutter-CRITICAL **: clutter_container_add_actor: assertion 'CLUTTER_IS_CONTAINER (container)' failed

在示例代码中,我注意到用于强制转换的 CLUTTER_STAGE 和 CLUTTER_CONTAINER 宏(这些显然对我不可用),但据我所知,它们只是执行了一些检查,然后进行了普通的 C 强制转换。如果这是不正确的,并且在施法之前需要对舞台指针进行一些 Gobject 类型的魔法,请告诉我。绑定和使用 clutter_stage_set_title 或 clutter_stage_set_colorcast(ClutterStage*)stage会导致分段错误,大概是同一个问题。

编辑:这是一个没有外部依赖项的精简示例(如果您不在 Linux 上,则需要将 dl 调用替换为操作系统的等效项)。此代码因段错误而失败,根据 GDB 和 Valgrind,该段错误位于clutter_stage_set_title (in /usr/lib/libclutter-glx-1.0.so.0.600.14)

4

2 回答 2

2

问题是您没有将 C 函数声明为extern(C). 因为 dmd 认为您正在调用 D 函数并使用错误的调用约定。正确执行此操作的一种方法是:

alias extern(C) void function(void*, const char*) setTitleFunc;
auto clutter_stage_set_title = getSym!(setTitleFunc)("clutter_stage_set_title");

我不确定如何在没有别名的情况下使其工作。DMD 拒绝解析extern(C)模板参数中的任何内容:

auto clutter_stage_set_title = getSym!(extern(C) void function(void*, const char*))("clutter_stage_set_title"); //Doesn't work

顺便说一句:您的cstring函数很危险:它返回一个 char* 表示可以修改字符串,但这并不总是正确的:如果您将字符串文字传递给toStringz它可能不会分配新内存,而是返回原始字符串的指针。字符串文字位于只读内存中,因此这可能会导致问题。

您可以调整您的函数类型以匹配 C 类型(const gchar*在 C 中 -->const char*在 D 中)并直接使用 toStringz。

于 2011-06-07T08:49:01.150 回答
0

D 中的结构不能相互继承,并且转换结构指针将返回 null 除非有中间转换void*(不像 C 转换)我在这里被驳斥

您最好使用句柄包装结构添加另一个抽象层,并在转换时模拟这些宏的检查

但是如果你这样做会发生什么

clutter_container_add_actor(cast(ClutterContainer*)(cast(void*)stage), textbox);

(先转换为 void*,然后转换为 ClutterContainer*)

于 2011-06-06T20:30:00.730 回答