Spec-Zone.ru › Ruby 3.4

класс Fiddle::Pointer

Родитель:
Объект

Fiddle::Pointer — это класс для работы с C-указателями

Атрибуты

ffi_ptr [Ч]

Публичные методы класса

[] (значение)

Получить базовый указатель для объекта Ruby val и вернуть его как объект Fiddle::Pointer.

Псевдоним для: to_ptr
from_native (значение, контекст)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 236
def self.from_native(value, ctx)
  self.new(value)
end
malloc (размер, освободить = nil) { |указатель| ... }
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 338
def self.malloc(size, free = nil)
  if block_given? and free.nil?
    message = "a free function must be supplied to #{self}.malloc " +
              "when it is called with a block"
    raise ArgumentError, message
  end

  pointer = new(LibC.malloc(size), size, free)
  if block_given?
    begin
      yield(pointer)
    ensure
      pointer.call_free
    end
  else
    pointer
  end
end

Примеры

# Automatically freeing the pointer when the block is exited - recommended
Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE) do |pointer|
  ...
end

# Manually freeing but relying on the garbage collector otherwise
pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE)
...
pointer.call_free

# Relying on the garbage collector - may lead to unlimited memory allocated before freeing any, but safe
pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE)
...

# Only manually freeing
pointer = Fiddle::Pointer.malloc(size)
begin
  ...
ensure
  Fiddle.free pointer
end

# No free function and no call to free - the native memory will leak if the pointer is garbage collected
pointer = Fiddle::Pointer.malloc(size)
...

Выделить size байтов памяти и связать их с необязательным freefunc.

Если блок задан, указатель будет передан в блок вместо возврата, а возвращаемое значение блока будет возвращено. Блок должен содержать freefunc.

Если freefunc задан, он будет вызван один раз, когда указатель будет собран сборщиком мусора или когда блок будет оставлен (если блок предоставлен), или когда пользователь вызовет call_free, в зависимости от того, что произойдет раньше. freefunc должен быть адресом, указывающим на функцию или экземпляр Fiddle::Function.

new (адрес, размер = nil, освободить = nil)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 300
def initialize(addr, size = nil, free = nil)
  ptr = if addr.is_a?(FFI::Pointer)
          addr

        elsif addr.is_a?(Integer)
          FFI::Pointer.new(addr)

        elsif addr.respond_to?(:to_ptr)
          fiddle_ptr = addr.to_ptr
          if fiddle_ptr.is_a?(Pointer)
            fiddle_ptr.ffi_ptr
          elsif fiddle_ptr.is_a?(FFI::AutoPointer)
            addr.ffi_ptr
          elsif fiddle_ptr.is_a?(FFI::Pointer)
            fiddle_ptr
          else
            raise DLError.new("to_ptr should return a Fiddle::Pointer object, was #{fiddle_ptr.class}")
          end
        elsif addr.is_a?(IO)
          raise NotImplementedError, "IO ptr isn't supported"
        else
          FFI::Pointer.new(Integer(addr))
        end

  @size = size ? size : ptr.size
  @free = free
  @ffi_ptr = ptr
  @freed = false
end
Fiddle::Pointer.new(адрес) → fiddle_cptr
new(адрес, размер) → fiddle_cptr
new(адрес, размер, freefunc) → fiddle_cptr
Исходный код
static VALUE
rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
{
    VALUE ptr, sym, size, wrap = 0, funcwrap = 0;
    struct ptr_data *data;
    void *p = NULL;
    freefunc_t f = NULL;
    long s = 0;

    if (rb_scan_args(argc, argv, "12", &ptr, &size, &sym) >= 1) {
        VALUE addrnum = rb_Integer(ptr);
        if (addrnum != ptr) wrap = ptr;
        p = NUM2PTR(addrnum);
    }
    if (argc >= 2) {
        s = NUM2LONG(size);
    }
    if (argc >= 3) {
        f = get_freefunc(sym, &funcwrap);
    }

    if (p) {
        TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
        if (data->ptr && data->free) {
            /* Free previous memory. Use of inappropriate initialize may cause SEGV. */
            (*(data->free))(data->ptr);
        }
        RB_OBJ_WRITE(self, &data->wrap[0], wrap);
        RB_OBJ_WRITE(self, &data->wrap[1], funcwrap);
        data->ptr  = p;
        data->size = s;
        data->free = f;
    }

    return Qnil;
}

Создать новый указатель на address с необязательным size и freefunc.

freefunc будет вызван при сборе мусора экземпляра.

read (адрес, длина)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 269
def self.read(addr, len)
  FFI::Pointer.new(addr).read_bytes(len)
end

Или считать память по адресу address длиной len и вернуть строку с этой памятью

to_native (значение, контекст)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 224
def self.to_native(value, ctx)
  if value.is_a?(Pointer)
    value.ffi_ptr

  elsif value.is_a?(Integer)
    FFI::Pointer.new(value)

  elsif value.is_a?(String)
    value
  end
end
to_ptr (значение)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 240
def self.to_ptr(value)
  if value.is_a?(String)
    cptr = Pointer.malloc(value.bytesize)
    cptr.ffi_ptr.put_string(0, value)
    cptr

  elsif value.is_a?(Array)
    raise NotImplementedError, "array ptr"

  elsif value.respond_to?(:to_ptr)
    ptr = value.to_ptr
    case ptr
    when Pointer
      ptr
    when FFI::Pointer
      Pointer.new(ptr)
    else
      raise DLError.new("to_ptr should return a Fiddle::Pointer object, was #{ptr.class}")
    end

  else
    Pointer.new(value)
  end
end

Получить базовый указатель для объекта Ruby val и вернуть его как объект Fiddle::Pointer.

Также псевдоним для: []
write (адрес, байты)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 265
def self.write(addr, bytes)
  FFI::Pointer.new(addr).write_bytes(bytes)
end

Записать байты в str в место, на которое указывает address.

Публичные методы экземпляра

+ (delta)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 440
def +(delta)
  self.class.new(to_i + delta, @size - delta)
end

Возвращает новый экземпляр указателя, который был сдвинут на n байт.

+@ ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 468
def +@
  ptr
end

Возвращает новый экземпляр Fiddle::Pointer, который является разыменованным указателем для этого указателя.

Аналогично оператору звездочки в C.

- (delta)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 444
def -(delta)
  self.class.new(to_i - delta, @size + delta)
end

Возвращает новый экземпляр указателя, который был сдвинут назад на n байт.

-@ ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 472
def -@
  ref
end

Возвращает новый экземпляр Fiddle::Pointer, который является ссылочным указателем для этого указателя.

Аналогично оператору амперсанда в C.

<=> (other)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 448
def <=>(other)
  return unless other.is_a?(Pointer)
  diff = self.to_i - other.to_i
  return 0 if diff == 0
  diff > 0 ? 1 : -1
end

Возвращает -1, если меньше, 0, если равно, 1, если больше other.

Возвращает nil, если ptr не может быть сравнен с other.

== (other)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 460
def ==(other)
  eql?(other)
end

Возвращает true, если other содержит тот же указатель, иначе возвращает false.

[] (index, length = nil)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 396
def [](index, length = nil)
  if length
    ffi_ptr.get_bytes(index, length)
  else
    ffi_ptr.get_char(index)
  end
rescue FFI::NullPointerError
  raise DLError.new("NULL pointer dereference")
end

Возвращает целое число, хранящееся по индексу.

Если заданы start и length, будет возвращена строка, содержащая байты, начиная с start длиной length.

[]= (*args, value)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 277
def []=(*args, value)
  if args.size == 2
    if value.is_a?(Integer)
      value = self.class.new(value)
    end
    if value.is_a?(Fiddle::Pointer)
      value = value.to_str(args[1])
    end

    @ffi_ptr.put_bytes(args[0], value, 0, args[1])
  elsif args.size == 1
    if value.is_a?(Fiddle::Pointer)
      value = value.to_str(args[0] + 1)
    else
      value = value.chr
    end

    @ffi_ptr.put_bytes(args[0], value, 0, 1)
  end
rescue FFI::NullPointerError
  raise DLError.new("NULL pointer access")
end

Set значение по index на int.

Или установить память по start до length с содержимым string, памятью из dl_cptr, или памятью, на которую указывает адрес памяти addr.

call_free ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 377
def call_free
  return if @free.nil?
  return if @freed
  if @free == RUBY_FREE
    LibC::FREE.call(@ffi_ptr)
  else
    @free.call(@ffi_ptr)
  end
  @freed = true
end

Вызвать функцию освобождения для этого указателя. Вызов более одного раза ничего не сделает. Ничего не делает, если функция освобождения не прикреплена.

eql? (other)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 455
def eql?(other)
  return unless other.is_a?(Pointer)
  self.to_i == other.to_i
end

Возвращает true, если other содержит тот же указатель, иначе возвращает false.

free ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 369
def free
  @free
end

Получить функцию освобождения для этого указателя.

Возвращает новый экземпляр Fiddle::Function.

См. Fiddle::Function.new

free= (free)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 373
def free=(free)
  @free = free
end

Set функцию освобождения для этого указателя на function в заданном Fiddle::Function.

freed? ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 388
def freed?
  @freed
end

Возвращает, была ли вызвана функция освобождения для этого указателя.

inspect ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 436
def inspect
  "#<#{self.class.name} ptr=#{to_i.to_s(16)} size=#{@size} free=#{@free.inspect}>"
end

Возвращает строку, отформатированную с легко читаемым представлением внутреннего состояния указателя.

null? ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 357
def null?
  @ffi_ptr.null?
end

Возвращает true, если это нулевой указатель.

ptr ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 464
def ptr
  Pointer.new(ffi_ptr.get_pointer(0))
end

Возвращает новый экземпляр Fiddle::Pointer, который является разыменованным указателем для этого указателя.

Аналогично оператору звездочки в C.

ref ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 476
def ref
  cptr = Pointer.malloc(FFI::Type::POINTER.size, RUBY_FREE)
  cptr.ffi_ptr.put_pointer(0, ffi_ptr)
  cptr
end

Возвращает новый экземпляр Fiddle::Pointer, который является ссылочным указателем для этого указателя.

Аналогично оператору амперсанда в C.

size ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 365
def size
  defined?(@layout) ? @layout.size : @size
end

Получить размер этого указателя.

size= (size)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 392
def size=(size)
  @size = size
end

Set размер этого указателя на size

to_i ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 406
def to_i
  ffi_ptr.to_i
end

Возвращает целое значение памяти этого указателя.

Также известен как: to_int
to_int ()

Возвращает целое значение памяти этого указателя.

Псевдоним для: to_i
to_ptr ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 361
def to_ptr
  @ffi_ptr
end
to_s (len = nil)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 412
def to_s(len = nil)
  if len
    ffi_ptr.get_string(0, len)
  else
    ffi_ptr.get_string(0)
  end
rescue FFI::NullPointerError
  raise DLError.new("NULL pointer access")
end

без 0

to_str (len = nil)
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 422
def to_str(len = nil)
  if len
    ffi_ptr.read_string(len)
  else
    ffi_ptr.read_string(@size)
  end
rescue FFI::NullPointerError
  raise DLError.new("NULL pointer access")
end
ptr.to_str        => string
ptr.to_str(len)   => string

Возвращает содержимое указателя в виде строки.

При вызове без аргументов этот метод вернет содержимое с длиной size этого указателя.

При вызове с len, будет возвращена строка из len байтов.

См. to_s

to_value ()
Исходный код
# File ext/fiddle/lib/fiddle/ffi_backend.rb, line 432
def to_value
  raise NotImplementedError, "to_value isn't supported"
end

Преобразовать этот указатель в объект ruby.

Ruby Core © 1993–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API