Subject:
Re: [ruby-ffi] Passing a struct by value, and typedef
From:
Maurizio De Santis
Date:
3/2/13 9:54 PM
To:
ruby-ffi@googlegroups.com

Thank you. Now, the code runs without errors:

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]


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?

--

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:
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 :)
--
 
---
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

--
 
---
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.