Строки в D — это просто массив символов. В языке C, все строки заканчиваются двоичным нулем. При взаимодействии с библиотеками, написанными на C, это необходимо учитывать. Как Phobos, так и Tango имеют методы для конвертации C-строк в D, и наоборот.
Разберем такой пример. Есть Си-шная функция: printf. Попробуем подсунуть ей массив с символами:
import tango.stdc.stdio; void main() { char[] string = "Hello"; printf("%s", &string); }На выходе, в консоли, получаем символ — ♣. Забавно. Функция printf, если вначале указать формат «%s», будет ожидать от последующих аргументов указатель на массив символов.
Поскольку по размеру тип char в C и D идентичен, я указываю &string, наивно полагая, что в результате получу указатель на первый элемент массива. Однако такая конструкция (&string) дает некорректные результаты потому, что в памяти массив представлен таким образом: сначала идет информация о длине массива, а потом данные.
Чтобы исправить ситуацию, нужно функции передавать именно данные, а не весь массив. Способов масса: можно сослаться (корректным для языка D способом) на первый элемент массива; можно воспользоваться встроенным свойством всех массивов в языке D — .ptr; или воспользоваться методом, который предлагает сам создатель языка: явно указать длину массива там, где возможно. Продемонстрирую кодом:
import tango.stdc.stdio; void main() { char[] string = "Hello"; printf("%s", &string[0]); // способ первый. Явно указываем // первый элемент массива printf("\n"); printf("%s", string.ptr); // второй способ. Используем встроенное свойство, // которое также указывает на первый // элемент массива printf("\n"); printf("%.*s", string.length, string.ptr); // третий способ. Явно указываем // на длину передаваемой строки printf("\n"); }Однако возникает вопрос: почему printf корректно выводит D-строки, ведь они не содержат двоичный ноль на конце? Ответ я нашел в скромной заметке про взаимодействие с языком Си: «[...] string literals, when they are not part of an initializer to a larger data structure, have a '\0' character helpfully stored after the end of them».
Указывается, что строковые литералы все-таки автоматически обзаводятся двоичным нулем. Получается, что никаких лишних телодвижений, кроме как правильной адресации, не требуется.
Я тоже пытаюсь освоить системный язык программирования. Сделал выбор за D. Так как C++ для моего мозга слишком сложен. Единственно, что меня смущает,
ОтветитьУдалитьэто сложность компиляции существующих оберток для GTK, SQLite и т.п.
Опять же непонятно как развивается сообщества языка, когда появится нормальная платформа для разработки GUI-программ. Чисто хакерский пока язык без нужных библиотек(основное приемущество java).
А какие проблемы с компиляцией GtkD? По мне, отличный биндинг, лучшего и не надо. Для GUI самое то.
Удалить