Строки в 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 самое то.
Удалить