Тема: INIConsole(пример использования LibIni)
Работаем с файлом настроек system.ini
Выводим в консоль названия секций, ключей и их значения шрифтом определённого цвета.
Функции для перебора всех секций и ключей(ini_enum_sections и ini_enum_keys) принимают в качестве аргумента функции обратного вызова(Callback), затем эти функции будут вызваны библиотекой для каждого ключа\секции.
В нашем примере внутри этих функций как раз и происходит вывод значений в консоль.
program INIConsole;
uses
KolibriOS, CRT;
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;
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;
type
TIniKeyCallback = procedure(FileName, SectionName, KeyName, KeyValue: PAnsiChar); stdcall;
TIniSectionCallback = procedure(FileName, SectionName: PAnsiChar); stdcall;
var
LibIni: Pointer;
LibIniLibInit: procedure;
ini_enum_sections: function(FileName: PAnsiChar; Callback: TIniSectionCallback): LongInt; stdcall;
ini_enum_keys: function(FileName, SectionName: PAnsiChar; Callback: TIniKeyCallback): LongInt; stdcall;
procedure IniKeyCallback(FileName, SectionName, KeyName, KeyValue: PAnsiChar); stdcall;
begin
TextColor(LightCyan);
Write(' ', KeyName);
TextColor(LightGray);
Write(' = ');
TextColor(White);
WriteLn(KeyValue);
end;
procedure IniSectionCallback(FileName, SectionName: PAnsiChar); stdcall;
begin
TextColor(Yellow);
WriteLn(SectionName);
ini_enum_keys(FileName, SectionName, IniKeyCallback);
end;
begin
InitConsole('INI Test');
LibIni := LoadLibrary('/sys/lib/libini.obj');
LibIniLibInit := GetProcAddress(LibIni, 'lib_init');
ini_enum_sections := GetProcAddress(LibIni, 'ini_enum_sections');
ini_enum_keys := GetProcAddress(LibIni, 'ini_enum_keys');
InitLibrary(LibIniLibInit);
ini_enum_sections('/sys/settings/system.ini', IniSectionCallback);
end.
Прикладываю также скомпилированный пример INIConsole.kex.
Если нам не нужно перебирать все секции и ключи, а нужно просто узнать значение конкретного ключа, то можно воспользоваться функциями ini_get_str и ini_get_int
var
ini_get_int: function(FileName, SecName, KeyName: PAnsiChar; DefVal: LongInt): LongInt; stdcall;
...............................
ini_get_int := GetProcAddress(LibIni, 'ini_get_int');
...............................
// присваиваем переменной MouseSpeed значение ключа speed из секции mouse файла system.ini
MouseSpeed := ini_get_int('/sys/settings/system.ini', 'mouse', 'speed', 0);
WriteLn('MouseSpeed = ', MouseSpeed);