Я создаю Окно в D, а функция CreateWindowA
требует указателей на символы, C массивы символов в основном.D Массивы типов в C Массивы стиля
Как преобразовать массив стиля D (char[]
) в массив стиля C (char*
)?
Я создаю Окно в D, а функция CreateWindowA
требует указателей на символы, C массивы символов в основном.D Массивы типов в C Массивы стиля
Как преобразовать массив стиля D (char[]
) в массив стиля C (char*
)?
Две функции, чтобы смотреть на, как правило, 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
преобразует строку в этот формат.
Причина, по которой я использую функции Windows-ASCII, заключается в том, что я не могу найти широкие функции внутри модуля core.sys.windows.windows, поэтому я пришел к выводу, что D не имеет реализованных функций. –
@JeroenBollen. Все, что требуется, это прототип функции, поэтому, если у druntime нет его по какой-либо причине, вы можете просто объявить его самостоятельно. Тем не менее, большинство программистов D, которые много делают с Windows API, используют http://www.dsource.org/projects/bindings/wiki/WindowsApi, который намного более совершенен, чем у druntime. –
Так что я мог бы просто сделать что-то вроде 'extern (Windows) void * CreateWindowW (...);', и это сработает? Не нужно было подключать внешние библиотеки или модули для включения? –
вы захватываете поле 0 массива D. и поле length
, чтобы захватить длину
однако, если вам нужна строка стиля C, вам нужен метод toStringz
, который добавит нулевой ограничитель и вернет указатель на первый символ. k
ЕЕРОВ ссылки на него, если апи не создает его собственная копия оперировать, чтобы избежать висячих указателей на GC
В общем, это правильно. Однако для функций Windows 'A' это не так, потому что, когда они принимают' char', они не используют UTF-8. Для них вам понадобится 'std.windows.charset.toMBSz'. –
«код, который имеет риск переполнения буфера, может напугать указатель из массива (с помощью' arr.ptr') »- из официального учебника, найденного через 2 минуты поиска в Интернете. –
@ H2CO3 Обычно это плохая идея, потому что строки D не имеют нулевого окончания, а строки C обычно являются. Передача 'ptr' функции C работает только тогда, когда она также занимает длину и не будет искать нулевой ограничитель в массиве, который он передал. –
@JonathanMDavis Точно (но передача явной длины часто является лучшей идеей в любом случае ...) –