Приведение ClutterActor * к ClutterStage * - PullRequest
2 голосов
/ 06 июня 2011

Я изучаю возможность создания привязки Clutter для языка D (http://d -programming-language.org / ) и начал пробовать несколько простых тестов с использованием динамической загрузки libclutter.Я столкнулся с проблемой, которая может возникнуть из-за системы наследования GObject, и я был бы признателен за любую помощь в ее выяснении.Вот краткое изложение: использование clutter_stage_get_default возвращает ClutterActor *, который я могу использовать с методами clutter_actor_ *.Но я всегда получаю ошибки или ошибки при использовании методов clutter_stage_ * или clutter_container_ *.Вот мой тестовый код: http://pastebin.com/nVrQ69dU

При вызове clutter_container_add_actor в строке 56 я получаю следующую ошибку: (<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_color с cast(ClutterStage*)stage привели к ошибкам сегментации, предположительно, к той же проблеме.

EDIT: Вот упрощенный пример без внешних зависимостей (если вы нев Linux вам нужно заменить вызовы dl эквивалентами вашей ОС).Этот код завершается с ошибкой segfault, которая согласно GDB и Valgrind находится в clutter_stage_set_title (in /usr/lib/libclutter-glx-1.0.so.0.600.14)

Ответы [ 2 ]

2 голосов
/ 07 июня 2011

Проблема в том, что вы не объявляете функции 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 опасна: она возвращает символ *, указывающий, что строка может быть изменена, но это не всегда так: если вы передаете строковый литерал в toStringz, это может не выделить новую память, но вместо этого верните указатель исходной строки. Строковые литералы находятся в постоянной памяти, поэтому это может привести к проблемам.

Вы можете просто настроить типы функций в соответствии с типами C (const gchar* в C -> const char* в D) и напрямую использовать toStringz.

0 голосов
/ 07 июня 2011

структуры в D не могут наследоваться друг от друга, и приведение указателей структуры вернет ноль, если нет промежуточного преобразования к void* (в отличие от преобразования C) Я получил здесь опровержение

Вам лучше добавить еще один слой абстракции, используя структуры для переноса дескрипторов, и эмулировать проверки из этих макросов при приведении

но что произойдет, если вы сделаете

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

(сначала приведение к void *, а затем к ClutterContainer *)

...