Как определить тип OC в FreePascal?

Модератор: Модераторы

Ответить
Andreich
постоялец
Сообщения: 268
Зарегистрирован: 17.04.2008 12:33:43

Как определить тип OC в FreePascal?

Сообщение Andreich »

Вопрос : Предположим имеется кросс платформенная программа на FreePascal / Lazarus. Использовать ее планируется как в Windows так и в Linux, но с некоторыми нюансами... Как определить в какой операционной системе запущено приложение?

Ответ : 1
Среда : -
Операционная система : Windows, Linux
Зависимости : -
Источник : http://freepascal.ru/forum/viewtopic.php?f=13&t=3633#p26455
Теги : операционная система, кросс платформенность

Я вот так делаю ^_^

Код: Выделить всё

{$IFDEF linux}
//some linux-specific code
{$ENDIF}
{IFDEF windows}
//some M$-specific code
{$ENDIF}

Чтобы быть точным, это позволяет определить, в какой системе (для какой системы) вы компилируете код. После запуска, проверять Windows или Linux - нет смысла. То, что написано под Linux, в Win не работет.
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Это позволит определить, запущена ли ваша windows-программа в вайне (линукс) или дарвайне (макось):

Код: Выделить всё

unit cl_winedetect;
{$mode delphi}
{$longstrings on}
interface
uses
  Windows, Classes, SysUtils;
function RunningInWine: longbool;
function GetZIsRoot: longbool;
implementation
  Const WineSig: string = 'Wine placeholder DLL';
  var
    Performed: boolean = false;
    Detected: boolean = false;
  function RunningInWine: longbool; //doesn't distignuish between wine and darwine
  var
    buf: string;
    S: TFileStream;
    i: integer;
    sd: string;
  begin
    if Performed then begin
      Result:=Detected;
      Exit;
    end;
    Result:=False;
    Try
      SetLength(sd, 1000);
      FillChar(sd[1], 1000, 0);
      GetSystemDirectory(@sd[1], 1000);
      sd:=Trim(sd);
      S:=TFileStream.Create(sd + '\kernel32.dll', fmOpenRead);
      SetLength(buf, 1000);
      S.ReadBuffer(buf[1], Length(buf));
      S.Free;
      For i:=1 to length(buf) - length(WineSig) do
        if copy (buf, i, length(WineSig)) = WineSig then begin
          Result:=True;
          Break;
        end;
    Except
    End;
    Detected:=Result;
    Performed:=true;
  end;

  function GetZIsRoot: longbool;
  begin
    Result:=FileExists('z:\usr\lib\libc.dylib')
          or FileExists('z:\usr\lib\libc.so');
  end;
end.
Max Rusov
постоялец
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Сообщение Max Rusov »

Другой способ определения Wine. Возвращает версию Wine, или пустую строку.

Код: Выделить всё

  function GetWineVersion :String;
  var
    H :THandle;
    vWineGetVersion :function :PChar; stdcall;
  begin
    Result := '';
    H := GetModuleHandle('ntdll.dll');
    if H <> 0 then begin
      vWineGetVersion := GetProcAddress(H, 'wine_get_version');
      if Assigned(vWineGetVersion) then
        Result := vWineGetVersion;
    end;
  end;
alex208210
постоялец
Сообщения: 207
Зарегистрирован: 12.05.2010 13:16:51

Сообщение alex208210 »

вопрос задан а ответа нет.. так как же все таки определить тип ос в freepascal?
Нужно что бы после запуска в зависимотси от ос, какой либо переменной в общем описании, присваивалось конкрентное значение. Элементарно можно проверить так: if directoryexists('/usr') then os:='linux' else os:='windows'; но это как то не правильно. может есть более продуманные способы?
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Код: Выделить всё

{$ifdef linux}
 os:='linux';
{$endif}
{$ifdef windows}
  {$ifdef wince}
    os:='wince';
  {$else}
    os:='windows;
  {$endif}
{$endif}
{$ifdef darwin}
  {$ifdef arm}
   os:='iOS';
  {$else}
    os:='MacOS X';
  {$endif}
{$endif}
{$ifdef freebsd}
  os:='FreeBsd';
{$endif}
{$ifdef beos}
 os:='BeOS';
{$endif}
и т.д.
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Сообщение Maxizar »

alex208210 думает, что можно написать вообще одно приложение (бинарник), который будет работать и в Винде и в Линукс и МакОси и.т.п (без перекомпиляции под каждую ось), по этому овтеты которые мы ему даем, его не устраивают, потому что последние работают тока при компиляции приложения. Такого вроде бы не возможно сделать, потому что у каждой ОС свое понимание программ(бинарников) и их содержания. Нельзя создать такое приложение (без перекомпиляции под каждую конкретнуюю ОС) а вот при перекомпиляции под каждую ОС можно, вам уже ответили как определить под какую ОС вы компилите, напичкав этих деректив, компилятор будет компилить бинарник под ту ОС которая выбрана, и делать бинарник именно под нее.
alex208210
постоялец
Сообщения: 207
Зарегистрирован: 12.05.2010 13:16:51

Сообщение alex208210 »

Maxizar, ты не правильно понимаешь что я думаю.. я думаю то что под каждую ос написаны свои функции с одинаковыми названиями но разной реализацией их работы заточеной под конкретную ос. поэтому такая функция как directoryexists работает как в бинарнике под винду так и под линукс, но выдает результат конкрентый каждой системе. А следовательно если ты скомпилишь одинаковый код в бинарник для винды и бинарник для линукса они оба будут работать, но выдавать результат свойственный своей системе. Возможно твое понимание было вызвано тем, что я не понял принципа реализации кода в первом сообщении.. поэтому вывод логичен)

Mr.Smart, спасибо! работает.
Последний раз редактировалось alex208210 25.05.2011 18:54:05, всего редактировалось 1 раз.
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Сообщение Maxizar »

Да такие функции есть и они завязаны на ядре, API и т.п под кажду ОС, но работают они почему? да потому что в исходниках LCL, FCL используются вот такие директивы как вам написал Mr.Smart, по этому при компиляции под Винду, Лазарус и Фри Паскаль использует, только те, которые именно для винды, когда вы компилите под Линукс, Лазарус смекает, и использует только функции для Линукса. Но это в момент компиляции... и это работает именно, так, но Вас это не устраивает, поэтому я предположил, что вы хотите другого... если ни того ни другого, я сдаюсь :cry:
alex208210
постоялец
Сообщения: 207
Зарегистрирован: 12.05.2010 13:16:51

Сообщение alex208210 »

в прошлом своем сообщении я дописал почему получилось так, что вы посчитали, что меня не устраивают директивы)) я не понмиал принципа реализации их в коде так как небыло наглядного примера, и строка some linux-specific code в котором написано "специфический для линукса" у меня вызвало мнене того, что там можно писать только то, что работает в линуксе а следовательно нельзя скомпилить под виндой. Теперь все понятно.
Ism
энтузиаст
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Сообщение Ism »

Товарищи, почему никто не говорит , что это директивы препроцессора (кажется так) ?
И все что включено в

Код: Выделить всё

{$IFDEF linux}
//some linux-specific code
{$ENDIF}

при компиляции в windows будет просто пропущено при компиляции, как будто этого кода нет.

так же и с содержимым директивы {$ifdef windows} в Linux

Это позволяет писать OS специфичный код и одни исходники будут компилироваться под все оси (с адаптацией под каждую)
Ответить