Ошибка InnoSetup "не удалось вызвать pro c" с вызовом внешней библиотеки DLL - PullRequest
0 голосов
/ 23 апреля 2020

Наш InnoSetup использует внешнюю библиотеку DLL для захвата и проверки файла xml для путей к файлам данных. Это работает нормально в большинстве случаев, Windows XP, 7, 10 (32 / 64bit). Но для некоторых пользователей это не получается, а для меня это не так в Crossover 19 для macOS 10.15. Поэтому сначала я добавил задержку загрузки в сценарий inno, чтобы обойти ошибку времени выполнения «not import dll».

Но потом я получаю сообщение «не могу вызвать pro c» во время выполнения. Отладчик InnoSetup указал мне на procedure GetExultGamePaths нашего скрипта.

Код в нашей dll:

extern "C" {
__declspec(dllexport) void __stdcall GetExultGamePaths(char *ExultDir, char *BGPath, char *SIPath, int MaxPath) {
    MessageBoxDebug(nullptr, ExultDir, "ExultDir", MB_OK);
    MessageBoxDebug(nullptr, BGPath, "BGPath", MB_OK);
    MessageBoxDebug(nullptr, SIPath, "SIPath", MB_OK);

    int p_size = strlen(ExultDir) + strlen("/exult.cfg") + MAX_STRLEN;
    char *p = new char[p_size];

    // Get the complete path for the config file
    Path config_path(ExultDir);
    config_path.AddString("exult.cfg");
    config_path.GetString(p, p_size);
    setup_program_paths();

    const static char *si_pathdef = CFG_SI_NAME;
    const static char *bg_pathdef = CFG_BG_NAME;

    MessageBoxDebug(nullptr, ExultDir, p, MB_OK);

    try {
        // Open config file
        Configuration config;
        if (get_system_path("<CONFIG>") == ".")
            config.read_config_file(p);
        else
            config.read_config_file("exult.cfg");

        std::string dir;

        // SI Path
        config.value("config/disk/game/serpentisle/path", dir, si_pathdef);
        if (dir != si_pathdef) {
            Path si(ExultDir);
            si.AddString(dir.c_str());
            si.GetString(SIPath, MaxPath);
        } else {
            std::strncpy(SIPath, si_pathdef, MaxPath);
        }

        // BG Path
        config.value("config/disk/game/blackgate/path", dir, bg_pathdef);
        if (dir != bg_pathdef) {
            Path bg(ExultDir);
            bg.AddString(dir.c_str());
            bg.GetString(BGPath, MaxPath);
        } else {
            std::strncpy(BGPath, bg_pathdef, MaxPath);
        }
    } catch (...) {
        std::strncpy(BGPath, bg_pathdef, MaxPath);
        std::strncpy(SIPath, si_pathdef, MaxPath);
    }

    delete [] p;
}

Часть скрипта InnoSetup

procedure GetExultGamePaths(sExultDir, sBGPath, sSIPath: String; iMaxPath: Integer);
external 'GetExultGamePaths@files:exconfig.dll stdcall delayload';

procedure CurPageChanged(CurPageID: Integer);
var
  sBGPath: String;
  sSIPath: String;
begin
  if CurPageID = DataDirPage.ID then begin
    if bSetPaths = False then begin
      setlength(sBGPath, 1024);
      setlength(sSIPath, 1024);
      GetExultGamePaths(ExpandConstant('{app}'), sBGPath, sSIPath, 1023 );

      BGEdit.Text := sBGPath;
      SIEdit.Text := sSIPath;
    end;
  end;

end;

The GetExultGamePaths(ExpandConstant('{app}'), sBGPath, sSIPath, 1023 ); - это то, что выдает ошибку «не удалось вызвать про c» во время выполнения.

Я понятия не имею, почему это происходит только в нескольких системах. Полный код для нашей dll и скрипта находится по адресу https://github.com/exult/exult/blob/master/win32/ Код dll находится в exconfig. *, А скрипт InnoSetup находится в exult_installer.iss

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...