Перейти к содержанию

Billy Bones

Пользователи
  • Активность

    8
  • Зарегистрирован

  • Посещение

  • Победитель дней

    2

Billy Bones стал победителем дня 29 марта

Billy Bones имел наиболее популярный контент!

Информация о Billy Bones

  • Звание
    Новичок
  1. Имя rt используется как параметр для компоновщика (в *nix системах ), а он, в свою очередь, компонует библиотеку, которая называется librt.so или librt.a (если используется статическая, версия библиотеки rt). Поэтому в Delphi нужно писать так: Unit Posix.Shm; // Посмотрите, может уже такой модуль есть ? Interface function shm_open(name : PAnsiChar; oflag : LongInt; mode : mode_t); Implementation Const LibRT = 'librt.so'; // Имя библиотеки. Нечего эту константу светить в секции Interface ! function shm_open(name : PAnsiChar; oflag : LongInt; mode : mode_t); external LibRT name 'shm_open'; End. PS: Рекомендую почитать книгу: Уильям Стивенс UNIX взаимодействие процессов. Там описано, если я точно помню, 2 механизма разделяемой памяти для Unix систем: Разделяемая память систем, являющихся потомками Unix Sys V. Разделяемая память Posix.
  2. Коли хвастался, значит нужно показать как это делается: Пишем такое консольное приложение: Program ownof; {$APPTYPE CONSOLE} {$R *.res} Type kernel_ulong_t = UInt64; kernel_long_t = Int64; TStat = packed record st_dev : kernel_ulong_t; st_ino : kernel_ulong_t; st_nlink : kernel_ulong_t; st_mode : UInt32; st_uid : UInt32; st_gid : UInt32; __pad0 : UInt32; st_rdev : kernel_ulong_t; st_size : kernel_long_t; st_blksize : kernel_long_t; st_blocks : kernel_long_t; st_atime : kernel_ulong_t; st_atime_nsec : kernel_ulong_t; st_mtime : kernel_ulong_t; st_mtime_nsec : kernel_ulong_t; st_ctime : kernel_ulong_t; st_ctime_nsec : kernel_ulong_t; __unused : array[0..2] of kernel_long_t; end; (* Функция mystat реализована на ассемблере. Откомпилирована в Linux и объектный файл перенесен в проект. *) function mystat(path_to_file : PAnsiChar; var S : TStat) : NativeUInt; external 'mystat.o' var S : TStat; Begin // Файл a.txt создан руками в том-же каталоге, куда помещается исполняемый // модуль данной программы. mystat('a.txt', S); Writeln('Owner is ', S.st_uid); End. Исходный код для mystat.asm: .text # function mystat(path_to_file : PAnsiChar; var S : TStat) : NativeUInt; # # Параметры: # rdi - path_to_file # rsi - @S # # Параметры функции помещаются, в те-же регистры, что и требует интерфейс системных # вызовов - не делаем ничего лишнего ! # # После выхода из режима ядра в регистре rax будет содержаться рузультат работы # системного вызова. Наша функция тоже возвращает рузультат в rax - не делаем # ничего лишнего ! .global mystat .align 16 mystat: movq $4, %rax # поместим номер системного вызова в регистр rax syscall # переходим в режим ядра ret Все данные для написания этой программы получены из исходных кодов ядра Linux 5.11.10. Данная реализация привязана к нескольким вещам: К архитектуре процессора (т.к. mystat написана на x86_64 ассемблере ) К ядру Linux (т.е. программа не будет работать на других Unix подобных ОС) К структуре с которой работает системный вызов sys_newstat (так называется, та процедура в ядре, что выполнает нужные нам действия). Способу выполнения системных вызовов (сам способ привязан к архитектуре процессора и к ядру ОС) Пока ничего из этого не поменяется всё будет ОК. И никаких Вам libc. PS: Номер системного вызова и его имя взято из файла arch/x86/entry/syscalls/syscall_64.tbl . Как делать системный вызов написано тут: arch/x86/entry/entry_64.S . Описание структуры взято из файла arch/x86/include/uapi/asm/stat.h
  3. Этот не подходит, т.к должен быть файл, конкретно, для платформы Linux: lib\linux64\release\Posix.SysStat.dcu. В своем прошлом посте, Я, описал процедуру, как самому собрать модуль Posix.SysStat.dcu: Создать проект консольного приложения. Скопировать в каталог с проектом файлы (см. список файлов и их расположение в прошлом посте - я его менял добавляя информацию). Включить в проект файл Posix.SysStat.pas - он сам добавится в uses. Добавить платформу Linux64 и сделать её активной. Выбрать кофигурацию Release Собрать консольное приложение - автоматически будет собран Posix.SysStat.dcu - он лежит в подкаталоге проекта linux64\Release. Выложить Posix.SysStat.dcu в lib\linux64\release. Всё.
  4. Это уже понятно . Тормозить, при изменении размеров окна (и вместе с ним ListView), начинает уже от 1000, а виртуалный ListBox в VCL и при 65535 не тормозит ! Очень не хотелось свои компоненты писать !
  5. Компилировать самому модуль Posix.SysStat.pas не нужно, т.к. он уже откомпилирован и лежит в: lib\linux64\debug - отладочная версия lib\linux64\release - релизная версия Компилятор его найдет, если путь к модулю указан в Tools | Options | Language | Delphi | Libraries | Library Path. А он, по умолчанию, там указан: $(BDSLIB)\$(Platform)\release Проверьте есть ли там откомпилированный модуль и прописан ли путь. Если модуля нет, то его можно откомпилировать самому - в каталоге source\rtl лежит файл buildrtl.bat - он собирает все библиотеки rtl. Процедура его использования не очень прозрачная. Где -то, в документации Embarcadero, написано как его правильно запустить. Суть, состоит в том, что перед его запуском, должны быть, правильно, установлены, некоторые переменные, среды окружения. Помню, что правил bin\rsvars.bat, и поменял там, все пути в стиле C:\Program Files (x86)\Embarcadero\Studio\21.0\XXXX на C:\RADStudio\XXX. Где RADStudio получен с помощью mklink /J RADStudio "С:\Program Files (x86)\Embarcadero\Studio\21.0" . Это нужно, т.к. многие утилиты командной строки, например make, не понимают пути с пробелами. Без этого rtl библиотеки не соберутся ! (по крайней мере не собираются c++ rtl, где всё на make построено) После того, как соберете rtl библиотеки, просто найдите Posix.SysStat.dcu (релизную версию, конечно ), и положите его в lib\linux64\release. Если, вдруг, модуль Posix.SysStat.dcu не соберется, то нужно будет искать, куда его нужно прописать, чтобы он собирался. Ха, Ха, Ха - а rll для Linux не собирается с помощью buildrtl.bat - только для Win32, Win64, OSX32. Значит нужно самому собрать. Создать свой проект, воткнуть туда исходники, прописать пути, если нужно, и откомпилировать. Изучите исходный код Posix.SysStat.pas - туда куча файлов включается includ'ом. На самом деле, к себе в проект (например консольного приложения), нужно скопиповать эти файлы (сохраняя структуру каталогов): source\rtl\posix в проекте как posix Posix.SysStat.pas Posix.SysStatAPI.inc Posix.Base.pas Posix.SysTypes.pas source\rtl\posix\linux в проекте как posix\linux BaseTypes.inc SysStatTypes.inc SysTypesTypes.inc Потом включить Posix.SysStat.pas, Posix.Base.pas, Posix.SysTypes.pas так: Uses Posix.SysStat in 'posix\Posix.SysStat.pas', Posix.Base in 'posix\Posix.Base.pas', Posix.SysTypes in 'posix\Posix.SysTypes.pas'; Добавляем платформу Linux64 и компилируем - Дело в шляпе. Выкладываем скомпилированный модуль в lib\linux64\release и дальше не паримся. В RAD Studio 10.4.2 по умолчанию всё на месте. Uses Posix.SysStat прекрасно работает.
  6. Получить UID (идентификатор пользователя - владельца) можно с помошью функции stat (Описана в POSIX стандарте : https://pubs.opengroup.org/onlinepubs/9699919799/ ). Далее есть файл /etc/passwd где UID пользователей сопоставлены с их именами. В Linux документацию на stat можно посмотреть командой man 2 stat (В случае если установлены средства разработки на языках C/C++). Если не ошибаюсь, она находится в библиотеке libc. Значит задача состоит в том, чтобы загрузить "dll" библиотеку libc ( например /usr/lib64/libc.so.6 ) и вызвать функцию stat. Для загрузки динамических библиотек (разделяемых объектов - shared object - so) используется вызов dlopen. Альтернативный способ состоит в том, чтобы напрямую (без библиотеки libc ) выполнить системный вызов stat, обратившись непосредственно к ядру ОС. Для этого, нужно, найти документацию на системный вызов stat, и вызвать его самому - вы по сути сами реализуете функционал библиотеки libc. Второй способ, хоть и кажется сложнее, на самом деле реализуется буквально несколькими assembler'ными инструкциями. Возможно в Delphi это уже сделали (не исключаю, что в какой-то библиотеке, уже есть функция Stat ). В RAD Studio, в каталоге source\rtl\posix, есть файл SysStatAPI.inc - он включен в posix.sysstat.pas. Значит просто: Uses Posix.SysStat и используйте функцию stat.
  7. Спасибо за совет, я не видел данного видео. ListView существенно экономнее расходует ОП, но вопрос был о том, имеется ли в FMX функционал, подобный виртуальному ListBox из VCL. Я посмотрел исходные коды для ListView и наверное, я сумею изобразить, что-то похожее, на виртуальный ListBox, установив свойство Adapter, у ListView, на определенный мной, класс - наследник от IListViewAdapter. Но увиденное в исходных кодах, немного настораживает, т.к. ListView, в некоторых своих методах, обращается, одновременно, и к элементу номер X, и к элементу номер Y - т.е. предполагается, что в данный момент времени, они оба существуют (Скорее всего, предполагается, что существуют элементы в диапазоне от 0 до Adapter.Count ). Я же, хотел избежать, выделения памяти, для структуры из элементов TListViewItem, содержащей Adapter.Count элементов. Именно этим свойством обладает виртуальный ListBox из VCL. Естественно, столько элементов не будет, но потенциально, может быть сколько угодно. И нужно быть к этому готовым. Данный функционал, нужен для настольного приложения под Linux. В Windows хватает и VCL. На смартфонах приложение разворачивать не планирутся никогда.
  8. У управляющего элемента TListBox, в библиотеке VCL, есть возможность, работать в виртуальном режиме ( Style = lbVirtual ), когда данные, для элементов списка, поставляет метод, связанный с событием OnData: Есть ли что-нибудь похожее в FireMonkey (FMX) ? Или придется для каждого элемента списка создавать объект класса TListBoxItem ? Попытка создать, таким образом, ListBox на 65536 элементов, приводит к диким расходам ОП - 248 MB:
×
×
  • Создать...