1

Тема: Console, BoxLib, OpenDial и другие библиотеки

Для серьезного программирования хотелось бы видеть обертки этих библиотек в отдельных модулях, со всеми экспортируемыми функциями. В будущем можно будет прикрутить к ним простое ООП. Глядишь, так больше на Delphi станет похоже, а не на Паскаль 80-х, как написали в комментарии ВК.

2

Re: Console, BoxLib, OpenDial и другие библиотеки

Freeman пишет:

как написали в комментарии ВК.

По поводу исключений уже было вроде

{68.24}   Function  SetExceptionHandler(Handler: Pointer; Mask: Dword; Var OldMask: Dword): Pointer; StdCall; External 'KolibriOS';
{68.25}   Function  SetExceptionActivity(Signal, Activity: Dword): Integer; StdCall; External 'KolibriOS';

По поводу обёрток, возможно может немного помочь обёртки для oberon-07
ещё есть немного примеров в теме про  XDS
Насчёт Visual Kolibri Library (VKL): не совсем понятно, будет ли это порт VCL, или аналог, написанный с нуля, или же это будут просто обёртки к существующим компонентам KolibriOS?
Имхо в плане GUI не стоит сильно рассчитывать на имеющиеся библиотеки.
Но Console и OpenDialog в любом случае нужны будут.
Я бы добавил ещё ColorDialog(это тоже в PROC_LIB как и OpenDialog) и InputBox.
Насчёт iconv трудно сказать, в CoreLite тоже кое-что есть.

Добавлено 2021-11-14 в 02:57

Планирую в качестве примера взаимодействия с библиотеками libimg, boxlib и buf2d переписать хотя бы частично раннюю версию Файлового навигатора(fNav).
Так же, как сделал это для GUI2D.
Это может показать различные нюансы использования этих библиотек.
Поможет понять, как именно их вообще стоит использовать в SDK.
В этой программе используются: элементы управления EditBox и ScrollBar из boxlib, загрузка изображений формата png с помощью libimg, рисование текста и изображений в буфер при помощи buf2d и вывод этого буфера на экран.
Как только сделаю — выложу в отдельной теме.

Добавлено 2021-11-21 в 00:30

Выложил в отдельной теме.
Работа с библиотеками пока ещё не вынесена в отдельные модули.

Добавлено 2021-12-05 в 01:04

Возможно, имеет смысл выделить отдельную тему и для библиотеки Buf2D чтобы не было путаницы потом?
У нас сейчас есть такие темы по библиотекам:

Ну а я пока продолжу выкладывать примеры для этих библиотек.
Следующий на очереди будет анимированный пример рисования.
Хочу переделать свою демку: сделать рисование сглаженными линиями и вывод с помощью библиотеки Buf2D.

Добавлено 2021-12-26 в 23:17

Я переписал процедуру InitLibrary, необходимую для инициализации некоторых библиотек, теперь она преимущественно на Pascal.
Она содержит в себе функции StrEqual и StrCopy — возможно, их лучше вынести отдельно в какой-нибудь другой модуль(SysUtils, например)
Также была исправлена неточность в коде этой процедуры, из-за чего некоторые библиотеки раньше инициализировались неверно
Так что, теперь в SDK нужно заменить на этот исправленный вариант

type
  Proc = procedure;

procedure InitLibrary(LibInit: Proc); stdcall;
const
  LIB_PATH = '/sys/lib/';

type
  PNameAddr = ^TNameAddr;
  TNameAddr = packed record
    Name: PAnsiChar;
    Addr: Pointer;
  end;

  PAddrName = ^TAddrName;
  TAddrName = packed record
    Addr: Pointer;
    Name: PAnsiChar;
  end;

  function StrEqual(Str1, Str2: PAnsiChar): Boolean;
  begin
    while (Str1^ = Str2^) and (Str1^ <> #0) do
    begin
      Inc(Str1);
      Inc(Str2);
    end;
    Result := Str1^ = Str2^;
  end;

  procedure StrCopy(StrFrom, StrTo: PAnsiChar);
  begin
    while (StrFrom^ <> #0) do
    begin
      StrTo^ := StrFrom^;
      Inc(StrFrom);
      Inc(StrTo);
    end;
  end;

  function DLLLoad(ImportTable: PAddrName): LongInt; stdcall;
  var
    ExportTable: PNameAddr;
    ProcAddr: Pointer;
    Name: PPAnsiChar;
    LibPath: array [0..32] of AnsiChar;
  begin
    Result := 1;
    StrCopy(LIB_PATH, LibPath);
    while ImportTable.Addr <> nil do
    begin
      StrCopy(ImportTable.Name, Pointer(LongInt(@LibPath) + Length(LIB_PATH)));
      ExportTable := LoadLibrary(LibPath);
      if ExportTable = nil then
        Exit;
      Name := PPAnsiChar(ImportTable.Addr);
      while Name^ <> nil do
      begin
        ProcAddr := GetProcAddress(ExportTable, Name^);
        if ProcAddr <> nil then
          Pointer(Name^) := ProcAddr
        else
          Exit;
        Inc(Name);
      end;
      if StrEqual(ExportTable.Name, 'lib_init') then
        InitLibrary(ExportTable.Addr);
      Inc(ImportTable);
    end;
    Result := 0;
  end;
asm
  pushad
  mov eax, offset MemoryAllocate
  mov ebx, offset MemoryFree
  mov ecx, offset MemoryReallocate
  mov edx, offset DLLLoad
  call LibInit
  popad
end;

Функции выделения\освобождения памяти остались те же, что и были:

function MemoryAllocate(Bytes: LongWord): Pointer; stdcall;
asm
        push ecx
        push ebx
        mov eax, 68
        mov ebx, 12
        mov ecx, Bytes
        int 64
        pop ebx
        pop ecx
end;

function MemoryReallocate(MemPtr: Pointer; Bytes: LongWord): Pointer; stdcall;
asm
        push ebx
        push ecx
        push edx
        mov eax, 68
        mov ebx, 20
        mov ecx, Bytes
        mov edx, MemPtr
        int 64
        pop edx
        pop ecx
        pop ebx
end;

function MemoryFree(MemPtr: Pointer): LongWord; stdcall;
asm
        push ecx
        push ebx
        mov eax, 68
        mov ebx, 13
        mov ecx, MemPtr
        int 64
        pop ebx
        pop ecx
end;

Загрузка и инициализация осуществляется как и раньше:

MyLib := LoadLibrary('/sys/lib/mylib.obj');
LibInit := GetProcAddress(MyLib, 'lib_init');
InitLibrary(LibInit);

Также я выложу пример использования в одном из следующих примеров.

Добавлено 2021-12-26 в 23:36

вот пример и вот пример

Добавлено 2022-01-23 в 00:36

Возможно, нашёл ошибку с загрузкой DLL из этой темы

...столкнулся с какой-то проблемой при совместном использовании библиотек.

Скорее всего, проблема из-за неправильной реализации функции StrCopy, вложенной в InitLibrary.
Вместо этого

procedure StrCopy(StrFrom, StrTo: PAnsiChar);
begin
  while (StrFrom^ <> #0) do
  begin
    StrTo^ := StrFrom^;
    Inc(StrFrom);
    Inc(StrTo);
  end;
end;

нужно так

procedure StrCopy(StrFrom, StrTo: PAnsiChar);
begin
  repeat
    StrTo^ := StrFrom^;
    Inc(StrFrom);
    Inc(StrTo);    
  until PAnsiChar(StrFrom - 1)^ = #0;
end;

3

Re: Console, BoxLib, OpenDial и другие библиотеки

0CodErr пишет:
  until PAnsiChar(StrFrom - 1)^ = #0;

Ого! Это повод поразмышлять... Или есть пруфы именно такой логики?

4

Re: Console, BoxLib, OpenDial и другие библиотеки

Freeman пишет:

Или есть пруфы именно такой логики?

Логика тут такая, что при копировании нуль-терминированных строк завершающий нулевой символ #0 тоже нужно копировать.