КАК, вам лучше задать этот вопрос на форуме rsdn.ru, я чувствую, что они более либеральны для новичков, чем DelphiMasters.Это все там, просто прочитайте с вниманием и вниманием.
1) вам вообще НЕ следует создавать DLL.Вы должны сделать BPL.DLL предназначена для взаимодействия с простым интерфейсом C, таким как Win32 API.Это самые примитивные типы без каких-либо побочных эффектов.C называют «машинно-независимым» ассемблером за его примитивность, а интерфейс DLL является своего рода.
DLL может использоваться для совместимости с другими языками, потому что они используют другие побочные эффекты, несовместимые с Delphi.Затем DLL обеспечивает наиболее примитивное взаимодействие, при этом все побочные эффекты удаляются из интерфейса.Понижая уровень взаимодействия до большинства упрощенных типов, интерфейс DLL обеспечивает совместимость.
Но когда вам нужно взаимодействовать с Delphi и Delphi, вам лучше разрешить Delphi заботиться обо всех проблемах совместимости.это то, для чего BPL создан в Delphi 3. Для этого просто нет причин использовать DLL.
Конечно, вы можете застрелиться в ноге, если хотите.https://forums.embarcadero.com/thread.jspa?threadID=64114
2) Вы не должны использовать WideString в XE2, а вместо этого использовать UnicodeString.Руководство по строкам особенно подчеркивает это.Похоже, вы просто не читали руководство.
3) строковые константы в Unicode.(но символьные константы находятся в ... в ANSI или в Unicode случайным образом, что приводит к неожиданным ошибкам в поведении).И нет необходимости просить и доверять чьим-либо словам - просто откройте свой exe в любом средстве просмотра и найдите эти константы, вы найдете их в 2-байтовой кодировке UCS-2 (aka WideChar).
4) ЮникодСпецификация используется для определения порядка байтов ЦП, будь то Intel или Motorola.Когда вы разрабатываете для Windows, у вас может быть только порядок байтов Intel, поэтому нет необходимости в спецификации.
5) весь параграф, который вы написали о длинах и размерах памяти, очень неоднозначен.Что вы имеете в виду под длиной, в каких единицах измерения она измеряется, откуда вы берете ее?
Я предполагаю, что под длиной вы подразумевали количество символов, не включающее какие-либо служебные структуры / символы "под капотом".Это то, что возвращает встроенная функция System.Length (строка или массив).Однако, если это предположение неверно, то и приведенный ниже ответ тоже становится неправильным.
И вопрос о том, следует ли вам умножить на 2, является просто признаком плохого кода.Вы всегда должны умножаться на что-то, годы назад вы уже должны умножаться.Умножить на ... что?По SizeOf (используется переменная типа char) или SizeOf (используется тип char).Тогда t будет Delphi, который автоматически определит, сколько памяти необходимо.И при работе с C-строкой вы должны использовать не длину, а длину + 1 - не забывайте о терминаторе # 0.
6) Как мы должны работать со строками ANSI в разных кодовых страницах Windows?Если мы получим строку ANSI с кодовой страницей 1200, должны ли мы перекодировать строку или работать с ней как есть?
RTFM !!!Просто объявите тип AnsiString с кодовой страницей 1200. или используйте RawByteStrnig и SetCodePage.Читайте настоящий код ниже.
Опять RTFM - это ВСЕ описано во встроенной справке.Это займет всего 2 часа, чтобы прочитать это ВСЕ во встроенной справке Delphi XE2.
7) как нам использовать класс TEncoding для преобразования между классами Unicode, UTF-8, WideString и AnsiString? TEncoding сделан для TStringList или чего-то в этом роде.Почему ты должен?Существует тип UTF8String - просто используйте его.
var as: AnsiString;ucs2s: строка;utf8string: UTF8String;... as: = ucs2;utf8s: = как;....
8) Существуют ли какие-либо серьезные ограничения производительности при использовании широких строк или строк Unicode? Это зависит от того, какой "Unicode" вы имеете в виду, UCS-2 или UTF8.И какие операции вы хотите использовать.Просто сделайте лунный цикл и измерьте время.
9) Должны ли мы написать наши интерфейсы, чтобы требовать параметры длины для типов параметров PChar, PAnsiChar и PWideChar? Это ваш выбор, делайте, как хотите.
Обычно PChar - это C-строка, заканчивающаяся # 0. И вот как работает функция StrLen.
Если вы игнорируете это соглашение и используете его как нетипизы Pointer - тогда передайте длину отдельно.
ВСЕ эти вопросы уже даны в помощь !!! Просто прочитайте это.
function CDF_File_Buffer.GetStringNoBounds(const ofs, len: integer): string;
// Распознать кодировку, не проверять адреса
var cntDOS, cntWin, cntWeird, i : Cardinal;
sBuf: RawByteString; cp: word;
ptr, ptr_i: PAnsiChar;
const rusDOS: set of AnsiChar = [#$80..#$AF, #$E0..#$F1];
rusWin: set of AnsiChar = [#$C0..#$FF];
begin
ptr := Pointer(Header); Inc(ptr, ofs);
case textCharset of
tcsGuess:
begin
ptr_i := ptr; cntDOS :=0; cntWin :=0; cntWeird:=0;
for i := 1 to len do begin
if ptr_i^ in rusDOS then Inc(cntDOS);
if ptr_i^ in rusWin then Inc(cntWin);
if (ptr_i^ < #32) or ((ptr_i^ >= #127) and not(ptr_i^ in rusWin) and not(ptr_i^ in rusDOS))
then inc(cntWeird);
Inc(ptr_i);
end;
if (cntWin > cntDOS) or (cntWeird > cntDOS) then cp := 1251 else cp := 866;
end;
tcsWin: cp := 1251;
tcsDOS: cp := 866;
else cp := 0; // быть не должно такого
end;
SetString(sBuf,ptr,len);
for i := 1 to Length(sBuf) do if sBuf[i] = #0 then sBuf[i] := #7;
// Не совсем корректно заменять нули, но
// 1) неизвестно, что вообще в этом поле может быть
// 2) файлы создаются в программе на C++, где нулей в строках не может быть
// 3) семантику надо выводить на экран, а Windows написана на C++
SetCodePage(sBuf, cp, false);
Result := string(sBuf);
end;
function CDF_File_Buffer.GetString(const ofs, len: integer; const min, max: integer): string;
begin
if (ofs <= 0) or (len <= 0) then
Exit( '--- нет текста ---');
if Cardinal(ofs + (len-1)) >= TotalSize then //меньше нуля уже не будет, убираем Warning
Exit('--- За пределами файла ---');
Result := '--- За пределами допустимой области: слишком близко к ';
if ofs < min then Exit(Result + 'началу ---');
if ofs + (len-1) > max then Exit(Result + 'концу ---');
Result := GetStringNoBounds(ofs, len);
end;
function CDF_File_Buffer.GetString(const ofs, len: integer): string;
begin
Result := GetString(ofs, len, 0, TotalSize-1);
end;