如何使用RtlMoveMemory()将char数组转换为String?

时间:2018-08-20 11:53:03

标签: inno-setup pascalscript

请在下面查看我的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;

谢谢。

1 个答案:

答案 0 :(得分:2)

很高兴,在尝试了几次可能的组合后,我终于使用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