Subject: Re: [ruby-ffi] Passing a struct by value, and typedef |
From: postmodern |
Date: 3/2/13 10:24 PM |
To: ruby-ffi@googlegroups.com |
a = LibGtop::GlibtopCpu.new
LibGtop.glibtop_get_cpu(a)
p a[:frequency]
This will allocate memory for a GlibtopCpu struct, pass the
pointer to the memory to glibtop_get_cpu and access to the struct
field within the memory. Once you are done with the "a" variable,
Ruby will just GC it and FFI will free the underlying memory.Thank you. Now, the code runs without errors:Another question: I initialized the pointer with clear = true, because the struct pointed by the pointer gets filled by glibtop_get_cpu, and then must be managed by Ruby, since glibtop_get_cpu just fills the struct. Am I wrong?
require 'ffi'
module LibGtop
extend FFI::Library
ffi_lib 'libgtop-2.0'
typedef :uint64, :guint64
attach_function :glibtop_get_cpu, [:pointer], :void
class GlibtopCpu < FFI::Struct
layout :flags, :guint64,
:total, :guint64,
:user, :guint64,
:nice, :guint64,
:sys, :guint64,
:idle, :guint64,
:iowait, :guint64,
:irq, :guint64,
:softirq, :guint64,
:frequency, :guint64,
:xcpu_total, [:guint64, 32],
:xcpu_user, [:guint64, 32],
:xcpu_nice, [:guint64, 32],
:xcpu_sys, [:guint64, 32],
:xcpu_idle, [:guint64, 32],
:xcpu_iowait, [:guint64, 32],
:xcpu_irq, [:guint64, 32],
:xcpu_softirq, [:guint64, 32],
:xcpu_flags, :guint64
end
end
# taken from https://github.com/ffi/ffi/wiki/Structs
pointer = FFI::MemoryPointer.new :uint64, LibGtop::GlibtopCpu.size, true
a = LibGtop::GlibtopCpu.new pointer
LibGtop.glibtop_get_cpu(a)
p a[:frequency]
--
--
Maurizio De Santis
2013/3/3 postmodern <postmodern.mod3@gmail.com>
You need to find out guint64's underlying type, and create the typedef in Ruby:
module LibGtop extend FFI::Library typedef :uint64, :guint64 end
On 03/02/2013 06:06 PM, Maurizio De Santis wrote:
You received this message because you are subscribed to the Google Groups "ruby-ffi" group.I am writing a libgtop2 wrapper using ffi in order to learn how to use ffi; I am new to ffi, so I have a lot of doubts.
libgtop2 lets get system and processes informations (cpu usage, memory usage, ...).
Here some informations about glibtop_get_cpu:
Library function `glibtop_get_cpu':
void glibtop_get_cpu (glibtop_cpu *buf);
void glibtop_get_cpu_l (glibtop *server, glibtop_cpu *buf);
Declaration of `glibtop_cpu' in `<glibtop/cpu.h>':
typedef struct _glibtop_cpu glibtop_cpu;
struct _glibtop_cpu
{
guint64 flags,
total,
user,
nice,
sys,
idle,
iowait,
irq,
softirq,
frequency,
xcpu_total [GLIBTOP_NCPU],
xcpu_user [GLIBTOP_NCPU],
xcpu_nice [GLIBTOP_NCPU],
xcpu_sys [GLIBTOP_NCPU],
xcpu_idle [GLIBTOP_NCPU],
xcpu_iowait [GLIBTOP_NCPU],
xcpu_irq [GLIBTOP_NCPU],
xcpu_softirq [GLIBTOP_NCPU],
xcpu_flags;
};
...
Here is what I wrote:
require 'ffi'
class GlibtopCpu < FFI::Struct
layout :flags, :guint64,
:total, :guint64,
:user, :guint64,
:nice, :guint64,
:sys, :guint64,
:idle, :guint64,
:iowait, :guint64,
:irq, :guint64,
:softirq, :guint64,
:frequency, :guint64,
:xcpu_total, :guint64,
:xcpu_user, :guint64,
:xcpu_nice, :guint64,
:xcpu_sys, :guint64,
:xcpu_idle, :guint64,
:xcpu_iowait, :guint64,
:xcpu_irq, :guint64,
:xcpu_softirq, :guint64,
:xcpu_flags, :guint64
end
module LibGtop
extend FFI::Library
ffi_lib 'libgtop-2.0'
attach_function :glibtop_get_cpu, [:pointer], :void
end
# taken from https://github.com/ffi/ffi/wiki/Structs
pointer = FFI::MemoryPointer.new :byte, GlibtopCpu.size, false
a = GlibtopCpu.new pointer
p LibGtop.glibtop_get_cpu(a)
Executing this gives (unsurprisingly) an error:
$ ruby lib/lib_gtop.rb
/home/izietto/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/ffi-1.4.0/lib/ffi/types.rb:57:in `find_type': unable to resolve type 'guint64' (TypeError)
from /home/izietto/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/ffi-1.4.0/lib/ffi/struct.rb:316:in `find_type'
from /home/izietto/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/ffi-1.4.0/lib/ffi/struct.rb:309:in `find_field_type'
from /home/izietto/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/ffi-1.4.0/lib/ffi/struct.rb:351:in `array_layout'
from /home/izietto/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/ffi-1.4.0/lib/ffi/struct.rb:261:in `layout'
from lib/lib_gtop.rb:4:in `<class:GlibtopCpu>'
from lib/lib_gtop.rb:3:in `<main>'
It doesn't find the guint64 type; how should I declare it?
Also: xcpu_total, xcpu_user are arrays... how should I declare them?
Finally... if someone could give me an explanation and an example of how to implement the bind to glibtop_get_cpu, I would appreciate it very much :) --
---
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-ffi+unsubscribe@googlegroups.com.
-- Blog: http://postmodern.github.com/ GitHub: https://github.com/postmodern Twitter: @postmodern_mod3 PGP: 0xB9515E77
---
You received this message because you are subscribed to the Google Groups "ruby-ffi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-ffi+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
-- Blog: http://postmodern.github.com/ GitHub: https://github.com/postmodern Twitter: @postmodern_mod3 PGP: 0xB9515E77