Subject:
[ruby-ffi] Re: Problem retrieving struct from pointer
From:
Joe
Date:
8/9/10 4:41 PM
To:
ruby-ffi



On Aug 5, 4:23 pm, Chuck Remes <cremes.devl...@mac.com> wrote:
> On Aug 5, 2010, at 8:12 AM, Joe wrote:
>
>
>
>
>
>
>
> > [snip]
> > typedef struct hba_AdapterAttributes {
> >    char    Manufacturer[64];
> >    char    SerialNumber[64];
> >    char    Model[256];
> >    char    ModelDescription[256];
> >    HBA_WWN NodeWWN;
> >    char    NodeSymbolicName[256];
> >    char    HardwareVersion[256];
> >    char    DriverVersion[256];
> >    char    OptionROMVersion[256];
> >    char    FirmwareVersion[256];
> >    HBA_UINT32      VendorSpecificID;
> >    HBA_UINT32      NumberOfPorts;
> >    char    DriverName[256];
> > } HBA_ADAPTERATTRIBUTES, *PHBA_ADAPTERATTRIBUTES;
>
> [snip]
> > ----------
>
> > In Ruby, I created the struct as so:
> > class HBA_AdapterAttributes < FFI::Struct
> >    layout :Manufacturer, :char
> >    :SerialNumber, :char,
> >    :Model, :char,
> >    :ModelDescription, :char,
> >    :NodeWWN, :uint8,
> >    :NodeSymbolicName, :char,
> >    :HardwareVersion, :char,
> >    :DriverVersion, :char,
> >    :OptionROMVersion, :char,
> >    :FirmwareVersion, :char,
> >    :VendorSpecificID, :uint32,
> >    :NumberOfPorts, :uint32,
> >    :DriverName, :char
> > end
>
> > Now def get_struct pointer
> > def get_struct pointer
> >    HBA::HBA_AdapterAttributes.new pointer
> > end
>
> > Calling the get_struct_pointer returns an array of fixnums, instead of
> > any string values.
>
> > Any idea what I'm overlooking here?
>
> Your FFI::Struct looks wrong for the char arrays/strings. You need to make sure the struct is allocating space for your string by telling it the length.
>
> class HBA_AdapterAttributes < FFI::Struct
>         layout :Manufacturer, [:char, 64],
>         :SerialNumber, [:char, 64],
>         :Model, [:char, 256],
>         :ModelDescription, [:char, 256],
>         :NodeWWN, :uint8, # this probably needs to be another struct
>         :NodeSymbolicName, [:char, 256],
>         :HardwareVersion, [:char, 256],
>         :DriverVersion, [:char, 256],
>         :OptionROMVersion, [:char, 256],
>         :FirmwareVersion, [:char, 256],
>         :VendorSpecificID, :uint32,
>         :NumberOfPorts, :uint32,
>         :DriverName, [:char, 256]
> end
>
> Check out the wiki athttp://wiki.github.com/ffi/ffi/structs
>
> Lots of good information there...
>
> cr- Hide quoted text -
>
> - Show quoted text -

Chuck, thanks for the response, it worked well.

Another question now if you don't mind.. you mentioned that for the
WWN, it needs to be a struct.  Just wondering how I would go about
doing this?

Previously, I passed a struct to the HBA_GetAdapterAttributes
function.  Since there isn't a function to do something similar, how
would I go about getting the string value of the Node WWN by using a
struct?

What I've tried is, created a new class to emulate the C struct:
  class HBA_Wwn < FFI::Struct
      layout :wwn, [:uint32, 8]
  end

In C:
  typedef struct HBA_wwn {
      HBA_UINT8 wwn[8];
  } HBA_WWN, *PHBA_WWN;

And from previously, I use the HBA_AdapterAttributes class, passing in
'attribs' as a struct.

  attribs = HBA::HBA_AdapterAttributes.new
  HBA::HBA_GetAdapterAttributes(i, attribs)
  wwnstruct = HBA::HBA_Wwn.new attribs[:NodeWWN].to_ptr
  puts "WWN: #{wwnstruct[:wwn]}"

Which isn't working out.  If you can't tell, I'm sort of hacking my
way through this :)

Thank you