Search code examples
inno-setuppascalscript

InnoSetup: How to pass a two dimensional string array to a function


Innosetup is killing me. I am getting a RUNTIME 'Type Mismatch' error, where it is, to me, quite unexpected. I am using Inno-setup 5.5.3 (u) (where the 'u' means the unicode version)

I am attempting to pass a two dimensional array into a method.

Here is my complete example.

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

[Messages]
SetupAppTitle=My Title

[Code]
var
    langMap : array[0..3] of array[0..1] of String;


function getMapVal(map : array of array[0..1] of String; key: String ) : String;
begin
    Result:='not testing the body of the method';
end;

function InitializeSetup(): Boolean;
begin
    MsgBox('Hello world.', mbInformation, MB_OK);

    getMapVal(langMap, 'hello');    // this line here fails with type mismatch! Why?

    Result := FALSE;
end;

This example would run, but for the invokation of the method:

getMapVal(langMap, 'hello');

It compiles, and therefore is happy with the declaration. But on invokation, mismatch error. What am I doing wrong?


Solution

  • First of all, you're not making a hash map, but a pure key value list. There's currently no way to make a real generics hash map in InnoSetup at this time. Anyway, your current code needs a complete refactor. I'd rather write it this way:

    [Setup]
    AppName=My Program
    AppVersion=1.5
    DefaultDirName={pf}\My Program
    
    [Code]
    type
      TKey = string;
      TValue = string;
      TKeyValue = record
        Key: TKey;
        Value: TValue;
      end;
      TKeyValueList = array of TKeyValue;
    
    function TryGetValue(const KeyValueList: TKeyValueList; const Key: TKey; 
      var Value: TValue): Boolean;
    var
      I: Integer;
    begin
      Result := False;
      for I := 0 to GetArrayLength(KeyValueList) - 1 do
        if KeyValueList[I].Key = Key then
        begin
          Result := True;
          Value := KeyValueList[I].Value;
          Exit;
        end;
    end;
    
    procedure InitializeWizard;
    var 
      I: Integer;
      Value: TValue;
      KeyValueList: TKeyValueList;
    begin
      SetArrayLength(KeyValueList, 3);
      for I := 0 to 2 do
      begin
        KeyValueList[I].Key := 'Key' + IntToStr(I);
        KeyValueList[I].Value := 'Value' + IntToStr(I);
      end;
    
      if TryGetValue(KeyValueList, 'Key2', Value) then
        MsgBox('Value: ' + Value, mbInformation, MB_OK);
    end;