2013-12-14 4 views
1

Я создаю Окно в D, а функция CreateWindowA требует указателей на символы, C массивы символов в основном.D Массивы типов в C Массивы стиля

Как преобразовать массив стиля D (char[]) в массив стиля C (char*)?

+1

«код, который имеет риск переполнения буфера, может напугать указатель из массива (с помощью' arr.ptr') »- из официального учебника, найденного через 2 минуты поиска в Интернете. –

+1

@ H2CO3 Обычно это плохая идея, потому что строки D не имеют нулевого окончания, а строки C обычно являются. Передача 'ptr' функции C работает только тогда, когда она также занимает длину и не будет искать нулевой ограничитель в массиве, который он передал. –

+0

@JonathanMDavis Точно (но передача явной длины часто является лучшей идеей в любом случае ...) –

ответ

5

Две функции, чтобы смотреть на, как правило, std.string.toStringz и std.utf.toUTFz.

toStringz преобразует string в immutable(char)*, которые вы можете передать в функцию C, которая принимает const char*. Если он может определить, что string имеет завершение с нулевой отметкой (что обычно имеет место только для строковых литералов, у которых есть нулевой терматор, который прошел их конец), то он не будет выделять и будет использовать только свойство ptr, но в большинстве случаев он будет выделять.

toUTFz преобразует любой тип строки в любой тип указателя символов. Скорее всего, он наиболее часто используется для преобразования в const(wchar)* для Windows, поскольку все функции W для Windows используют UTF-16, но его также можно использовать для преобразования в char* - например. str.toUTFz!(char*)(). Например, toStringz, он постарается не выделять, может ли он определить, что это не нужно, но это почти всегда необходимо.

Теперь, для вашего конкретного случая, вы пытаетесь использовать одну из функций A в Windows. Это почти всегда плохая идея, и я бы настоятельно советовал ей. Используйте toUTFz, чтобы преобразовать string в const(wchar)* и передать это CreateWindowW. AFAIK, единственным преимуществом функций A является то, что они работают с pre-Win2K. Все остальное о них хуже. Однако, если по какой-то причине вы настаиваете на использовании функций A, тогда вам придется использовать std.windows.charset.toMBSz, потому что функции A не принимают UTF-8, а скорее «набор символов Windows 8-бит» и toMBSz преобразует строку в этот формат.

+0

Причина, по которой я использую функции Windows-ASCII, заключается в том, что я не могу найти широкие функции внутри модуля core.sys.windows.windows, поэтому я пришел к выводу, что D не имеет реализованных функций. –

+0

@JeroenBollen. Все, что требуется, это прототип функции, поэтому, если у druntime нет его по какой-либо причине, вы можете просто объявить его самостоятельно. Тем не менее, большинство программистов D, которые много делают с Windows API, используют http://www.dsource.org/projects/bindings/wiki/WindowsApi, который намного более совершенен, чем у druntime. –

+0

Так что я мог бы просто сделать что-то вроде 'extern (Windows) void * CreateWindowW (...);', и это сработает? Не нужно было подключать внешние библиотеки или модули для включения? –

3

вы захватываете поле 0 массива D. и поле length, чтобы захватить длину

однако, если вам нужна строка стиля C, вам нужен метод toStringz, который добавит нулевой ограничитель и вернет указатель на первый символ. k ЕЕРОВ ссылки на него, если апи не создает его собственная копия оперировать, чтобы избежать висячих указателей на GC

+1

В общем, это правильно. Однако для функций Windows 'A' это не так, потому что, когда они принимают' char', они не используют UTF-8. Для них вам понадобится 'std.windows.charset.toMBSz'. –

Смежные вопросы