PWideChar — Тип Delphi


Содержание
Илон Маск рекомендует:  Как разместить статью на codenet ru

В чем разница между W >

Я обновляю некоторый древний (с 2003 года) код Delphi до Delphi Architect XE, и у меня возникают некоторые проблемы. Я получаю ряд ошибок, когда есть несовместимые типы. Эти ошибки не происходят в Delphi 6, поэтому я должен предположить, что это потому, что вещи были обновлены.

Честно говоря, я не знаю, в чем разница между PAnsiChar и PWideChar, но Delphi точно знает разницу и не даст мне скомпилировать. Если бы я знал, в чем заключаются различия, возможно, я мог бы выяснить, что использовать или как это исправить.

2 ответа

Коротко: до Delphi 2009 нативный тип строки в Delphi имел обыкновение быть ANSI CHAR: каждый символ в каждой строке был представлен как 8-битный символ. Начиная с Delphi 2009, строки Delphi стали UNICODE с использованием нотации UTF-16: теперь базовый Char использует 16 бит данных (2 байта), и вам, вероятно, не нужно много знать о кодовых точках Unicode, которые представлены в виде двух последовательные 16-битные символы.

8-битные символы называются «анси-символы». PAnsiChar — это указатель на 8-битные символы. 16-битные символы называются «широкими символами». PWideChar — это указатель на 16-битные символы. Delphi знает разницу и преуспевает, если не позволяет вам смешивать оба!

Больше информации

Вы можете найти более подробную информацию о переносе Delphi в Unicode здесь: Новая Белая книга: Миграция Delphi Unicode для простых смертных

Вы также можете найти SO для «Миграция Delphi Unicode».

Пару лет назад тип символов по умолчанию в Delphi был изменен с AnsiChar (однобайтовая переменная, представляющая символ ANSI) на WideChar (двухбайтовая переменная, представляющая символ UTF16.) Тип char теперь является псевдонимом WideChar вместо AnsiChar тип string теперь является псевдонимом UnicodeString (версия Unicode UTF-16 традиционного типа строки Delphi) вместо AnsiString , а тип PChar теперь является псевдонимом PWideChar вместо PAnsiChar .

Компилятор может сам позаботиться о многих преобразованиях, но есть несколько проблем:

  1. Если вы используете типы строковых указателей, такие как PChar , вам нужно убедиться, что указатель указывает на правильный тип данных, и компилятор не всегда может это проверить.
  2. Если вы передаете строки в параметры var , тип переменной должен быть точно таким же. Это может быть более сложным теперь, когда у вас есть два типа строк для работы.
  3. Если вы используете string как удобный буфер байтового массива для хранения произвольных данных вместо переменной, содержащей текст, это не будет работать как UnicodeString . Убедитесь, что они объявлены как RawByteString как обходной путь.
  4. Везде, где вы имеете дело с длиной строки в байтах, например, при чтении или записи в / из TStream, убедитесь, что ваш код не предполагает, что длина char составляет один байт.

Взгляните на Delphi Unicode Migration for Mere Mortals, чтобы узнать о некоторых хитростях и советах, как заставить это работать. Это не так сложно, как кажется, но и не тривиально. Удачи!

PWideChar — Тип Delphi

Профиль
Группа: Завсегдатай
Сообщений: 3439
Регистрация: 13.11.2002
Где: в столице

Репутация: 2
Всего: 60

Код
var CompName: PWideChar;
begin
edit1.text := ‘192.168.172.229’;
CompName := PWideChar(edit2.text);
showmessage(CompName);
end;

Профиль
Группа: Модератор
Сообщений: 11360
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 483

Snowy
Дата 20.11.2006, 11:22 (ссылка) | (нет голосов) Загрузка .
Код
CompName := PWideChar(WideString(edit2.text));

Профиль
Группа: Завсегдатай
Сообщений: 3439
Регистрация: 13.11.2002
Где: в столице

Репутация: 2
Всего: 60

Cashey
Дата 20.11.2006, 11:26 (ссылка) | (нет голосов) Загрузка .

Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

Репутация: 17
Всего: 50

Matematik
Дата 20.11.2006, 11:26 (ссылка) | (нет голосов) Загрузка .
Google
Дата 12.11.2020, 00:05 (ссылка)

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) — крупнейшем в рунете сборнике материалов по Дельфи

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

Загадочный тип PCHAR

Здравствуйте, дельфисты! Сегодня вам поведую, что это за тип PCHAR. И как его корректно использовать. Этот тип упоминается во всех API функциях, которые принимают в качестве параметра какое-либо строковое значение.

Сначала я расскажу вам про тип string. Тип string является главным преимуществом языка Pascal над языком С. Именно из-за этого типа программы, написанные на Pascal, весят больше, чем программы, написанные на С. Все знают, что тип string является массивом, котором каждый элемент является типом CHAR (следовательно, юникодовский тип WideString — массив из WideChar). Только размер этого массива неизвестен заранее и при каждом присваивании его длина изменяется. Но так же можно и при объявлении ограничить размер строки. Но размер строки ограничивается только формально, потому что нельзя обратиться к элементу массива больше чем размер строки указанной в разделе var. Конечно, размер каждой строки должен быть не более 2ГБ, примерно 2 миллиарда символов (для widestring 1 миллиард символов, так как один символ задаётся 2 байтами). Так как строка это массив, следовательно, через квадратные скобки можно обращаться к каждому элементу массива.

После данных манипуляций переменная str будет равна ‘ProgLammersclub.ru’, замечу, что первый символ в строке имеет индекс 1. Так как тип string и тип array of char сходны следователь их можно присвоить друг к другу. Но, при присваивании переменной массива переменной строки будет ошибка, так как у массива мы жёстко задаём размер массива, а у строки мы не знаем длину даже при её ограничении.

Обращаться к 55 символу переменной str2 уже нельзя, но физически в памяти он существует. При получении указателя на строку возвращается адрес первого символа в строке, значит, такие выражения одинаковы:

Теперь тип PCHAR. Фактически тип PCHAR это указатель на тип CHAR. Это понятно и потому как он назван. По «программеским» правилам при объявлении нового типа типизированных указателей берётся тип, на который указывает указатель и спереди ставится буква P. Вот его объявление:

Ну, если этот тип указывает на только один символ, то, как же функции понимают параметры, которые мы передаём им. Всё очень просто. Каждая строка, переданная в качестве параметра какой либо функции должна иметь в конце символ #0. Функция по указателю находит первый символ строки и идёт дальше пока не наткнётся на символ #0. Delphi автоматизировала преобразование строки когда в параметре мы указываем саму строку: MessageBox(0,’привет’,’привет’,0) здесь автоматика, а почему не автоматика при указывании переменных я не знаю. Мы всегда пишем

Всё нормально. Тот же результат при использовании указателей.

Это потому что массивы обычно заполняются нулями.

Пример 1: Совсем другая история:

В сообщении перед двойкой стоит какой то символ. Это потому что нумерация в Delphi может начинаться с любого индекса, в данном случае она начинается 1, а 0 символ не используется. Значит то, что я вам сказал в начале это неправильно:

А массив выводится нормально, потому что Delphi автоматически правит указатель на массив.

Пример 2: Не знаю почему, но вместо двоек выводится не пойми что. Мистика.

Отсюда понятно что изначально все переменные заполняются нулями. И переменная STR тому не исключение.

Пример 4: Интересная ситуация:

Как видите в заголовке есть символы ‘hs’ потом квадратик потом двойки. Всему есть разумное объяснение. Строка STR_ARR не кончается нулём, следовательно, функция не нашла нуль только в конце строки STR_ARR и пошла дальше к переменной STR, поэтому строка STR_ARR получилась такой длинной. Квадратик в после строки ‘hs’ понятен из первого примера.

Вот такие пироги. Изначально казалось, что тип string проще и лучше, а получилось как всегда! Тип string принёс нам массу неприятностей. Поэтому C++ намного популярнее Delphi. Вот такими словами кончается моя очередная статья.

Несовместимые типы: «PAnsiChar» и «PW >

Я очень новичок в delphi XE8. У меня есть следующий код, который из моей версии delphi 6, и я хочу запустить его в delphi XE8.

когда я пытаюсь запустить его, ошибка указывает на строки 8 и 25 в коде с сообщением об ошибке

У меня есть поиск везде для решения, но я просто не могу решить проблему. Пожалуйста, помогите.. Спасибо.

    19 2
  • 11 авг 2020 2020-08-11 05:36:28
  • ErenRavenHeart

2 ответа

LPCSTR
Указатель на постоянную строку с нулевым завершением 8-битных символов Windows (ANSI).
Этот тип объявляется в WinNT.h следующим образом:
typedef __nullterminated CONST CHAR *LPCSTR;

LPSTR
Указатель на строку с нулевым завершением 8-битных символов Windows ( ANSI).
Этот тип объявляется в WinNT.h следующим образом:
typedef CHAR *LPSTR;

Проблема, связанная с вашим кодом, состоит в том, что аргумент lpMultiByteStr для каждой функции является PAnsiChar , и вы передаете PChar в качестве параметра.
PChar является псевдонимом PAnsiChar в Delphi 6 и означает PWideChar в Delphi XE8.

Вы можете решить эту проблему в строке # 8, объявив, что вы работаете (и вызываете ее соответственно) следующим образом:
function UTF8ToStringLen(const src: PAnsiChar; const Len: Cardinal): WideString;

Чтобы решить проблему в строке 25, измените объявление функции следующим образом:
function StringToUTF8Len(const src: PAnsiChar; const Len: Cardinal): string; и «печально известная» строка:
bsiz := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Temp), -1, PAnsiChar(Result), bsiz, nil, nil);

  • 11 авг 2020 2020-08-11 05:36:29
  • fantaghirocco

В Delphi 2007 и ранее PChar является псевдонимом для PAnsiChar . В Delphi 2009 и более поздних версиях PChar является псевдонимом для PWideChar . Поэтому, изменяя компилятор, вы меняете смысл кода.

Вы можете решить это просто, заменив PChar на PAnsiChar , и код будет иметь свое первоначальное значение.

В современном Unicode Delphi было бы более естественно использовать string (псевдоним UnicodeString ) вместо COM WideString . Вы также можете использовать одну из многих подпрограмм библиотеки для преобразования UTF-8.

У вас наверняка будут другие проблемы. Я рекомендую вам читать технический документ Marco Cantpaper на Unicode в Delphi в качестве следующего шага.

Incompatible types: ‘PAnsiChar’ and ‘PW > Ask Question

I am very new in delphi XE8. I have this following code which is from my delphi version 6 and I want to run it in delphi XE8.

when I try to run it the error points to line 8 and 25 in the code with an error message saying

I have search everywhere for the solution but I just cant solve the problem. Please help.. Thank you.

2 Answers 2

In Delphi 2007 and earlier, PChar is an alias for PAnsiChar . In Delphi 2009 and later, PChar is an alias for PWideChar . So by changing compiler you change the meaning of the code.

You can resolve this simply by replacing PChar with PAnsiChar and the code will have its original meaning.

In modern Unicode Delphi it would be more natural to use string (alias of UnicodeString ) instead of the COM WideString . You might also use of one the many library routines to perform UTF-8 conversion.

There are surely going to be other issues ahead of you. I recommend that you read Marco Cantù’s whitepaper on Unicode in Delphi as your next move.

LPCSTR
A pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
This type is declared in WinNT.h as follows:
typedef __nullterminated CONST CHAR *LPCSTR;

LPSTR
A pointer to a null-terminated string of 8-bit Windows (ANSI) characters.
This type is declared in WinNT.h as follows:
typedef CHAR *LPSTR;

The issue related to your code is that the argument lpMultiByteStr of each function is a PAnsiChar and you’re passing a PChar as a parameter.
The PChar is an alias of PAnsiChar in Delphi 6 and stands for a PWideChar in Delphi XE8.

You can solve this issue at line #8 declaring you function (and calling it accordingly) like this:
function UTF8ToStringLen(const src: PAnsiChar; const Len: Cardinal): WideString;

To solve the issue at line #25, change the function declaration like:
function StringToUTF8Len(const src: PAnsiChar; const Len: Cardinal): string;
and the «infamous» line:
bsiz := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Temp), -1, PAnsiChar(Result), bsiz, nil, nil);

Несовместимые типы: ‘PAnsiChar’ и ‘PW >

этот вопрос уже есть ответ здесь:

Я очень новичок в delphi XE8. У меня есть следующий код, который из моей версии delphi 6, и я хочу запустить его в delphi XE8.

когда я пытаюсь запустить его, ошибка указывает на строки 8 и 25 в коде с сообщением об ошибке

у меня поиск везде для решения, но я просто не могу решить проблему. Пожалуйста помочь.. Спасибо.

2 ответов

в Delphi 2007 и более ранних, PChar псевдоним PAnsiChar . В Delphi 2009 и выше, PChar псевдоним PWideChar . Таким образом, изменяя компилятор, вы изменяете значение кода.

вы можете решить эту проблему, просто заменив PChar с PAnsiChar и код будет иметь свое первоначальное значение.

в современном Unicode Delphi было бы более естественно использовать string (псевдоним UnicodeString ) вместо COM WideString . Вы также можете использовать один из многих библиотек процедуры для выполнения преобразования UTF-8.

там, безусловно, будут другие вопросы впереди вас. Я рекомендую вам прочитать белый лист Марко Канту на Unicode в Delphi как твой следующий шаг.

LPCSTR
Указатель на постоянную строку с нулевым завершением 8-разрядных окон (в ANSI) символов.
Этот тип объявлен в WinNT.H следующим образом:
typedef __nullterminated CONST CHAR *LPCSTR;

LPSTR
Указатель на строку с нулевым завершением 8-разрядных окон (в ANSI) символов.
Этот тип объявлен в WinNT.H следующим образом:
typedef CHAR *LPSTR;

проблемы, связанные с вашим кодом заключается в том, что аргумент lpMultiByteStr каждой функции PAnsiChar и вы проезжаете PChar в качестве параметра.
на PChar — это псевдоним из PAnsiChar на Delphi 6 и стоит PWideChar на Дельфи X Е8.

вы можете решить эту проблему в строке #8, объявив вам функцию (и вызвав ее соответственно) следующим образом:
function UTF8ToStringLen(const src: PAnsiChar; const Len: Cardinal): WideString;

чтобы решить проблему в строке #25, измените объявление функции, например:
function StringToUTF8Len(const src: PAnsiChar; const Len: Cardinal): string;
и «пресловутого» строку:
bsiz := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Temp), -1, PAnsiChar(Result), bsiz, nil, nil);

Несовместимые типы: «PAnsiChar» и «PWideChar»

Я очень новый в Дельфах X Е8. У меня есть этот следующий код, который с моей DELPHI версии 6 и я хочу, чтобы запустить его в Дельфах X Е8.

когда я пытаюсь запустить его точки ошибок в линии 8 и 25 в коде с сообщением об ошибке, говоря

У меня есть искать везде для решения, но я просто не могу решить эту проблему. Пожалуйста, помогите .. Спасибо.

В Delphi 2007 и более ранние версии, PChar является псевдонимом PAnsiChar . В Delphi 2009 и более поздних версий, PChar является псевдонимом PWideChar . Таким образом, изменяя компилятор изменить значение кода.

Вы можете решить эту проблему путем простой замены PChar с PAnsiChar и код будет иметь свое первоначальное значение.

В современной Unicode Delphi было бы более естественно использовать string (псевдоним класса UnicodeString ) вместо COM WideString . Вы также можете использовать один из многих библиотечных подпрограмм для выполнения преобразования UTF-8.

Там наверняка будет другие вопросы перед вами. Я рекомендую вам прочитать официальный документ Марко Канта на Unicode в Delphi , как ваш следующий шаг.

LPCSTR
Указатель на постоянную строку с нулевым символом в конце 8-битных ОС Windows ( ANSI символов).
Этот тип объявлен в WinNT.h следующим образом :
typedef __nullterminated CONST CHAR *LPCSTR;

LPSTR
Указатель на строку с нулевым символом в 8-битных ОС Windows ( ANSI символов).
Этот тип объявлен в WinNT.h следующим образом :
typedef CHAR *LPSTR;

Проблема , связанная с вашим кодом является то , что аргумент lpMultiByteStr каждой функции есть PAnsiChar и вы передаете в PChar качестве параметра. Является псевдонимом в Delphi 6 и обозначает в Delphi X Е8 .
PChar PAnsiChar PWideChar

Вы можете решить эту проблему на линии № 8, объявляя вы действуете (и назвав его соответствующим образом), как это:
function UTF8ToStringLen(const src: PAnsiChar; const Len: Cardinal): WideString;

Для решения этой проблемы на линии № 25, изменить объявление функции , как:
function StringToUTF8Len(const src: PAnsiChar; const Len: Cardinal): string;
и « печально известной » линии:
bsiz := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Temp), -1, PAnsiChar(Result), bsiz, nil, nil);

В каждом конкретном случае решение Дэвида Хеффернэн в относится.

Несовместимые типы: «PAnsiChar» и «PWideChar»

Я очень новичок в delphi XE8. У меня есть следующий код, который из моей версии delphi 6, и я хочу запустить его в delphi XE8.

когда я пытаюсь запустить его, ошибка указывает на строки 8 и 25 в коде с сообщением об ошибке

У меня есть поиск везде для решения, но я просто не могу решить проблему. Пожалуйста, помогите.. Спасибо.

В Delphi 2007 и ранее PChar является псевдонимом для PAnsiChar . В Delphi 2009 и более поздних версиях PChar является псевдонимом для PWideChar . Поэтому, изменяя компилятор, вы меняете смысл кода.

Вы можете решить это просто, заменив PChar на PAnsiChar , и код будет иметь свое первоначальное значение.

В современном Unicode Delphi было бы более естественно использовать string (псевдоним UnicodeString ) вместо COM WideString . Вы также можете использовать одну из многих подпрограмм библиотеки для преобразования UTF-8.

У вас наверняка будут другие проблемы. Я рекомендую вам читать технический документ Marco Cantpaper на Unicode в Delphi в качестве следующего шага.

LPCSTR
Указатель на постоянную строку с нулевым завершением 8-битных символов Windows (ANSI).
Этот тип объявляется в WinNT.h следующим образом:
typedef __nullterminated CONST CHAR *LPCSTR;

LPSTR
Указатель на строку с нулевым завершением 8-битных символов Windows ( ANSI).
Этот тип объявляется в WinNT.h следующим образом:
typedef CHAR *LPSTR;

Проблема, связанная с вашим кодом, состоит в том, что аргумент lpMultiByteStr для каждой функции является PAnsiChar , и вы передаете PChar в качестве параметра.
PChar является псевдонимом PAnsiChar в Delphi 6 и означает PWideChar в Delphi XE8.

Вы можете решить эту проблему в строке # 8, объявив, что вы работаете (и вызываете ее соответственно) следующим образом:
function UTF8ToStringLen(const src: PAnsiChar; const Len: Cardinal): WideString;

Чтобы решить проблему в строке 25, измените объявление функции следующим образом:
function StringToUTF8Len(const src: PAnsiChar; const Len: Cardinal): string; и «печально известная» строка:
bsiz := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Temp), -1, PAnsiChar(Result), bsiz, nil, nil);

PWideChar — Тип Delphi

It can also be used to point to characters within a WideString, as in the example code.

As with other pointers, integer arithmetic, such as Inc and Dec can be performed on a PWideChar variable, also shown in the example.

Правила форума «Delphi: Общие вопросы»

Notes
PWideChar is principally used when processing null-terminated (C-like) strings.
Related commands
$ExtendedSyntax Controls some Pascal extension handling
Dec Decrement an ordinal variable
Inc Increment an ordinal variable
PAnsiChar A pointer to an AnsiChar value
PChar A pointer to an Char value
PWideString Pointer to a WideString value
WideChar Variable type holding a single International character
WideString A data type that holds a string of WideChars
Example code : Display all characters in a string
// Full Unit code.
// ————————————————————
// You must store this code in a unit called Unit1 with a form
// called Form1 that has an OnCreate event called FormCreate.

unit Unit1;

uses
// The System unit does not need to be defined
Forms, Dialogs;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;

var
Form1: TForm1;

implementation
<$R *.dfm>// Include form definitions

В чем разница между W >

Я обновляю некоторый древний (с 2003 года) код Delphi до Delphi Architect XE, и у меня возникают некоторые проблемы. Я получаю ряд ошибок, когда есть несовместимые типы. Эти ошибки не происходят в Delphi 6, поэтому я должен предположить, что это потому, что вещи были обновлены.

Честно говоря, я не знаю, в чем разница между PAnsiChar и PWideChar, но Delphi точно знает разницу и не даст мне скомпилировать. Если бы я знал, в чем заключаются различия, возможно, я мог бы выяснить, что использовать или как это исправить.

2 ответа

Коротко: до Delphi 2009 нативный тип строки в Delphi имел обыкновение быть ANSI CHAR: каждый символ в каждой строке был представлен как 8-битный символ. Начиная с Delphi 2009, строки Delphi стали UNICODE с использованием нотации UTF-16: теперь базовый Char использует 16 бит данных (2 байта), и вам, вероятно, не нужно много знать о кодовых точках Unicode, которые представлены в виде двух последовательные 16-битные символы.

8-битные символы называются «анси-символы». PAnsiChar — это указатель на 8-битные символы. 16-битные символы называются «широкими символами». PWideChar — это указатель на 16-битные символы. Delphi знает разницу и преуспевает, если не позволяет вам смешивать оба!

Больше информации

Вы можете найти более подробную информацию о переносе Delphi в Unicode здесь: Новая Белая книга: Миграция Delphi Unicode для простых смертных

Вы также можете найти SO для «Миграция Delphi Unicode».

Пару лет назад тип символов по умолчанию в Delphi был изменен с AnsiChar (однобайтовая переменная, представляющая символ ANSI) на WideChar (двухбайтовая переменная, представляющая символ UTF16.) Тип char теперь является псевдонимом WideChar вместо AnsiChar тип string теперь является псевдонимом UnicodeString (версия Unicode UTF-16 традиционного типа строки Delphi) вместо AnsiString , а тип PChar теперь является псевдонимом PWideChar вместо PAnsiChar .

Компилятор может сам позаботиться о многих преобразованиях, но есть несколько проблем:

  1. Если вы используете типы строковых указателей, такие как PChar , вам нужно убедиться, что указатель указывает на правильный тип данных, и компилятор не всегда может это проверить.
  2. Если вы передаете строки в параметры var , тип переменной должен быть точно таким же. Это может быть более сложным теперь, когда у вас есть два типа строк для работы.
  3. Если вы используете string как удобный буфер байтового массива для хранения произвольных данных вместо переменной, содержащей текст, это не будет работать как UnicodeString . Убедитесь, что они объявлены как RawByteString как обходной путь.
  4. Везде, где вы имеете дело с длиной строки в байтах, например, при чтении или записи в / из TStream, убедитесь, что ваш код не предполагает, что длина char составляет один байт.

Взгляните на Delphi Unicode Migration for Mere Mortals, чтобы узнать о некоторых хитростях и советах, как заставить это работать. Это не так сложно, как кажется, но и не тривиально. Удачи!

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL