Вызов имени приложения FMX OSX - PullRequest
0 голосов
/ 03 января 2019

Я прошу прощения, если это тривиальный вопрос, но я искал столько, сколько могу и не могу найти какое-либо решение.

У меня есть приложение Delphi / FMX, которое создает DLL для Win32 и DYLIB дляmacOS (High Sierra), 32 бита.

В устройстве я просто использовал GetModuleName(hInstance), чтобы получить имя модуля, который использовал устройство, и это отлично работает в Win32 и Win64.Например, если основная программа использует устройство, оно вернет имя основной программы.Однако, если DLL, используемая основной программой, использует модуль, она вернет имя DLL.Я использую это для создания отдельных файлов журнала для основной программы и любых библиотек DLL, которые она вызывает, и использую имя, перенастроенное в имени файла журнала.

Код, который работает (в единице, используемой DYLIB (OSX) / DLL (Win32), созданной с FMX) в Windows:

sModuleName := TPath.GetFileNameWithoutExtension(GetModuleName(hInstance));

GetModulename находится вдля модуля System.SysUtils и AFAIK не существует условного определения для Windows / OSX и т. д. Мое предположение, очевидно ошибочное, заключается в том, что он должен работать при сборке для OSX.Это не так, он висит на этой строке без ошибок, просто «(не отвечает)» в окне FORCE QUIT.Я пробовал это как на виртуальной машине MacOS, так и на жесткой системе MacOS с тем же результатом.

Есть ли что-то еще, что мне нужно сделать, чтобы GetModuleName работал с OSX?

и/ или

Есть ли что-то (похожее), которое получит имя модуля, если я соберу для OSX?

Ответы [ 2 ]

0 голосов
/ 08 января 2019

GetModuleName также существует в MacOS.Я думаю, что ваша проблема не в том, что функция не существует, а в том, что вы не должны вызывать ее из раздела initialization.В общем, вы должны избегать вызова других dll / dylibs в разделе инициализации, чтобы не вызывать блокировку загрузчика.

0 голосов
/ 04 января 2019

Как уже отмечалось, проблема в том, что модуль журнала не знает, откуда на него ссылаются, но модуль / модуль, на который ссылаются, знает свое имя?

Так что обходной путь (и егоэто обходной путь), чтобы переместить фактический вызов в функцию, которая создает файл журнала, из блока Initialze в блоке файла журнала (т. е. поместить его в функцию с именем LogFileSetup с одним параметром: именем вызывающего модуля) ивызов этой функции в начале блока инициализации вызывающего устройства.Так в вызывающем модуле, например:

initialization

  // Setup the log file
  if not(LogFileSetup('MyModuleName')) then
    ShowMessage('Logfile setup error');

И функция в модуле LogFile (для справки я использую Log4Pascal, который бесплатный, простой и работает):

function LogFileSetup(sModuleName : string): Boolean;
begin
    try
      Result := True;
      {$IFDEF MSWINDOWS}
      sLogFolder := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'logs';
      {$ENDIF MSWINDOWS}
      {$IFDEF MACOS}
      sLogFolder := IncludeTrailingPathDelimiter(GetHomePath) + 'Library/Logs/MyAppName';
      {$ENDIF MACOS}

      if not(DirectoryExists(sLogFolder)) then
        ForceDirectories(sLogFolder);

      sLogFile := IncludeTrailingPathDelimiter(sLogFolder) + sModuleName + '_' + FormatDateTime('YYYYMMDD', now) + '_' + FormatDateTime('hhmmsszzz',now) + '.log';
      EMPLogger := TLogger.Create(sLogFile);
      EMPLogger.getLogLevel;

      // INFO log message
      EMPLogger.Info('[Log4Pascal] Logging commenced');
    except
      Result := False;
    end;
end;

Конечно, если у кого-то есть ответ на вопрос: существует ли OSX, эквивалентный:

  GetModuleName(hInstance)

Это было бы отлично.

...