【问题标题】:How to convert a char array to String using RtlMoveMemory()?如何使用 RtlMoveMemory() 将 char 数组转换为 String?
【发布时间】:2018-08-20 11:53:03
【问题描述】:

请看下面我的CharArrayToString()

为此目的声明RtlMoveMemory函数的正确方法是什么,以及如何调用它?

[Setup]
AppName=EmptyProgram
AppVerName=EmptyProgram 1
UsePreviousAppDir=false
DefaultDirName={pf}\EmptyProgram
Uninstallable=false
OutputBaseFilename=HelloWorld
PrivilegesRequired=lowest

[Messages]
SetupAppTitle=My Title

[Code]

function lstrlen(lpString: array of Char
    ): Integer; external 'lstrlenW@kernel32.dll stdcall';

procedure RtlMoveMemory_ToString(
    Dest  : String;
    Source: PAnsiChar;
    Length: Integer
    ); external 'RtlMoveMemory@kernel32.dll stdcall';

//-------------------------------------------------------------------------------------------------
// This function is provided only for demonstration
//-------------------------------------------------------------------------------------------------
procedure StringToCharArray(const sStr: String; var aCharArray: array of Char);
var
  iLenStr: Integer;
  iIdx   : Integer;

begin
  iLenStr := Length(sStr);
  if iLenStr = 0 then Exit;

  SetArrayLength(aCharArray, iLenStr + 1);  // Include a room for the null terminator

  for iIdx := 1 to iLenStr do begin
    aCharArray[iIdx - 1] := sStr[iIdx];
  end;
  aCharArray[iIdx - 1] := #0;
end;  // ==> StringToCharArray()
//=================================================================================================

//-------------------------------------------------------------------------------------------------
// This function is an obvious solution to convert a char array to String.
// I do not want to use this function if possible.
//-------------------------------------------------------------------------------------------------
function CharArrayToString_deprecated(const aCharArray: array of Char): String;
var
  iLenCharArray: Integer;
  iIdx         : Integer;

begin
  iLenCharArray := lstrlen(aCharArray);
  if iLenCharArray = 0 then Exit;

  SetLength(Result, iLenCharArray);

  for iIdx := 0 to iLenCharArray - 1 do
    Result[iIdx + 1] := aCharArray[iIdx];
end;  // ==> CharArrayToString_deprecated()
//=================================================================================================

//-------------------------------------------------------------------------------------------------
// I want to use RtlMoveMemory() to achieve this, but currently it does not work.
// What is the correct way to declare RtlMoveMemory() for this purpose, and how to call it?
//-------------------------------------------------------------------------------------------------
function CharArrayToString(const aCharArray: array of Char): String;
var
  iLenCharArray: Integer;
  iIdx         : Integer;

begin
  iLenCharArray := lstrlen(aCharArray);  // This length is not including the null terminator
  if iLenCharArray = 0 then Exit;

  SetLength(Result, iLenCharArray);
  RtlMoveMemory_ToString(Result, aCharArray[0], iLenCharArray * 2);
end;  // ==> CharArrayToString()
//=================================================================================================

//-------------------------------------------------------------------------------------------------
procedure Test();
var
  aCharArray: array of Char;
  sDummy    : String;
  sResult   : String;

begin
  sDummy := '1234567';
  StringToCharArray(sDummy, aCharArray);

  // Let's assume aCharArray is returned by a Windows API function

  // Of course, this one succeeds
  // sResult := CharArrayToString_deprecated(aCharArray);

  // I need an advice to make this one works
  sResult := CharArrayToString(aCharArray);

  // Report the resultant string from the char array
  MsgBox('String: ' + sResult + #13#10 +
         'Length: ' + IntToStr(Length(sResult)),
         mbInformation, MB_OK);
end;  // ==> Test()
//=================================================================================================

function InitializeSetup(): Boolean;
begin
  Test();
  Result := FALSE;
end;

提前致谢。

【问题讨论】:

  • CharArrayToString_deprecated 有什么问题?
  • @MartinPrikryl,当要转换的数据很大时,可能会获得更好的性能。 :-)
  • 使用AnsiString 而不是array of char。然后您可以使用来自stackoverflow.com/a/39845057/850848 的代码

标签: inno-setup pascalscript


【解决方案1】:

很高兴,通过反复试验尝试了几种可能的组合后,我终于设法使用RtlMoveMemory函数将数据从array of char复制到String

procedure RtlMM_CharArrayToStr(
    sDest        : String;  // in
    var achSource: Char;    // in
    const iLength: Integer  // in
    ); external 'RtlMoveMemory@kernel32.dll stdcall';

function CharArrayToString(const aCharArray: array of Char): String;
var
  iLenCharArray: Integer;

begin
  iLenCharArray := lstrlen(aCharArray);  // This length is not including the null terminator
  if iLenCharArray = 0 then Exit;

  SetLength(Result, iLenCharArray);
  RtlMM_CharArrayToStr(Result, aCharArray[0], iLenCharArray * 2);
end;  // ==> CharArrayToString()

感谢 Martin Prikryl 的提示。

更新

为了完整起见,这是我使用RtlMoveMemory 函数将数据从String 复制到array of char 的函数:

procedure RtlMM_StrToCharArray(
    sDest        : array of Char;  // in
    const sSource: String;         // in
    const iLength: Integer         // in
    ); external 'RtlMoveMemory@kernel32.dll stdcall';

procedure StringToCharArray(const sStr: String; out aCharArray: array of Char);
var
  iLenStr: Integer;

begin
  iLenStr := Length(sStr);
  if iLenStr = 0 then Exit;

  SetArrayLength(aCharArray, iLenStr + 1);  // Include a room for a null terminator
  RtlMM_StrToCharArray(aCharArray, sStr, iLenStr * 2);
  aCharArray[iLenStr] := #0;
end;  // ==> StringToCharArray

【讨论】:

    猜你喜欢
    • 2011-08-13
    • 1970-01-01
    • 2013-08-26
    • 2012-11-19
    • 2012-09-03
    • 2011-01-26
    • 1970-01-01
    • 2012-11-04
    相关资源
    最近更新 更多