Current time: 14.04.2024, 12:34 Hello There, Guest! (LoginRegister)
Language: english | russian  

Post Reply 
Threaded Mode | Linear Mode
Lua. Руководства
» Без обсуждения
Author Message
Berserker Offline
Administrators

Posts: 16471
Post: #2

Системное программирование.

Работа с памятью.

Для низкоуровневого доступа к памяти можно использовать модуль era.mem

Code:
function mem.float (ptr, value)
function mem.double (ptr, value)
function mem.i32 (ptr, value)
function mem.i16 (ptr, value)
function mem.i8 (ptr, value)
function mem.u32 (ptr, value)
function mem.u16 (ptr, value)
function mem.u8 (ptr, value)

Указанный набор функций позволяет считывать данные по числовому адресу (если опущен второй аргумент) или записывать (если оба аргумента присутствуют).

i = integer, целочисленный
u = unsigned integer, беззнаковое целое число
Число после символа — размер данных в битах.
float и double позволяют работать с float32 и float64 (числа с плавающей запятой).

Пример
Data\Scripts\test.sys.lua
Code:
local mem = require('era.mem') -- загрузили модуль era.mem и сохранили его в локальной переменной

mem.i32(0x887668, 777)        -- записали 777 в v1 как целое 4-байтное число со знаком
local byte = mem.u8(0x401000) -- считали байт по адресу 0x401000

Другие полезные функции:

function mem.addr (ptr)
Преобразовывает адрес в виде ffi.cdata в обычное число. Возвращает обычное число в неизменном виде.

function mem.ptr (ptr)
Преобазовывает адрес или указатель в void*-указатель типа ffi.cdata

function mem.val (ptr)
Принимает адрес или указатель. Возвращает объединение (union) типа ffi.cdata:

Code:
union {
  int        v;
  void*      ptr;
  float*     f32;
  double*    f64;
  int32_t*   i32;
  uint32_t*  u32;
  int16_t*   i16;
  uint16_t*  u16;
  int8_t*    i8;
  uint8_t*   u8;
  char*      text;
}

Данное объединение позволяет изменять адрес указателя как обычное число (поле v) и получать типизированные данные по адресу.

Пример.
Code:
local v1 = mem.val(0x887668)
v1.f32[0] = 3.14 -- записали в v1 (адрес ЕРМ-переменной) число 3.14 ординарной точности

Доступен метод :str, аналогичный mem.str, позволяющий трактовать объединение как строку.
Code:
v1:str('Hi!') -- записывать в первые байты переменной v1 значение 'Hi'\0

function mem.ofs (ptr, offset)
По адресу/указателю и смещению возвращает новый адрес типа void*.
Пример: mem.ofs(0x400000, 0x1000)

function mem.str (ptr, str, bufSize)
Читает или записывает строку по адресу ptr. Последний аргумент — опциональный размер буфера, отведённый под строку.

Пример.
Code:
local text = mem.str(0x500000)      -- прочитать нуль-терминированную строку по адресу 0x500000
mem.str(0x500000, 'Привет, мир', 4) -- записать строку 'При'\0 по тому же адресу, ограничить размер буфера 4-мя символами, включая #0

Для удобства и повышения скорости работы модуль предоставляет готовые псевдонимы для популярных типов данных языка C:

Code:
mem.pvoid   = ffi.typeof('void*')
mem.pchar   = ffi.typeof('char*');
mem.intptr  = ffi.typeof('intptr_t')
mem.pfloat  = ffi.typeof('float*')
mem.pdouble = ffi.typeof('double*')
mem.pi32    = ffi.typeof('int32_t*')
mem.pi16    = ffi.typeof('int16_t*')
mem.pi8     = ffi.typeof('int8_t*')
mem.pu32    = ffi.typeof('uint32_t*')
mem.pu16    = ffi.typeof('uint16_t*')
mem.pu8     = ffi.typeof('uint8_t*')


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
05.01.2018 15:21
Find all posts by this user Quote this message in a reply
« Next Oldest | Next Newest »
Post Reply 


Messages In This Thread
Lua. Руководства - Berserker - 05.01.2018, 04:39
RE: Lua. Руководства - Berserker - 05.01.2018 15:21

Forum Jump:

Powered by MyBB Copyright © 2002-2024 MyBB Group