2013-08-29 2 views
2

Innosetup убивает меня. Я получаю ошибку RUNTIME Type Mismatch, где она для меня, совершенно неожиданная. Я использую Inno-setup 5.5.3 (u) (где «u» означает версию Unicode)InnoSetup: Как передать массив двумерных строк в функцию

Я пытаюсь передать двумерный массив в метод.

Вот мой полный пример.

[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; 

Этот пример будет работать, но для invokation метода:

getMapVal (langMap, 'Привет');

Он компилируется и поэтому доволен декларацией. Но при вызове ошибка несоответствия. Что я делаю не так?

ответ

2

Прежде всего, вы не создаете карту хэша, а список значений чистого ключа. В настоящее время в InnoSetup в настоящий момент нет возможности создать реальную карту хэша дженериков. Во всяком случае, ваш текущий код нуждается в полном рефакторе. Я бы предпочел написать его так:

[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; 
+0

спасибо за этот интересный пример. Одна вещь, которую я замечаю сейчас, поскольку я хотел бы иметь возможность упростить «вставку» элементов (а не только получение), похоже, нет «pass by referennce» ?? Это так? то есть невозможно переместить код «вставки» в процедуру, выполнить вставку внутри этого метода (и ожидать, что значения будут оставаться там, как только процедура завершится)? – svaens

+0

Это пример того, как вы должны реализовать список ключевых значений строк. Другими словами, ваш код, но реорганизован. То, о чем вы просите, является темой для другого вопроса, так как я не знаю, что вы имеете в виду. – TLama

+0

Нет, извините, неважно. В то время как у меня были проблемы с моим собственным кодом, в (повторном) тестировании (правильно на этот раз), я обнаружил, что совершил ошибку. У меня нет проблем с тем, что я упомянул в предыдущем комментарии. В очередной раз благодарим за помощь. – svaens