Subject:
[ruby-ffi] Re: Arrays in Structs and Unions
From:
Quintus
Date:
2/4/10 1:23 PM
To:
ruby-ffi

I'm sorry, here's the attaching of the function:

attach_function :get_version_ex, :GetVersionExW,
[:buffer_inout], :bool

Marvin

On 4 Feb., 20:21, Quintus <sutn...@gmx.net> wrote:
> Hi,
>
> I've two questions. This is the more important one: How to use arrays
> in Structs via FFI? I have this nice struct declaration:
> ----------------------------------------------------
> typedef struct _OSVERSIONINFO {
>   DWORD dwOSVersionInfoSize;
>   DWORD dwMajorVersion;
>   DWORD dwMinorVersion;
>   DWORD dwBuildNumber;
>   DWORD dwPlatformId;
>   TCHAR szCSDVersion[128];} OSVERSIONINFO;
>
> ----------------------------------------------------
> ( Fromhttp://msdn.microsoft.com/en-us/library/ms724834%28VS.85%29.aspx
> , to be used with the GetVersionInfoEx() function:http://msdn.microsoft.com/en-us/library/ms724451%28VS.85%29.aspx)
> and I'm not sure how to access the szCSDVVersion[128] member. I
> thought, I had to work with Memory pointers for arrays, but the
> following code doesn't work for me:
> -----------------------------------------------------
> class OSVersionInfo < FFI::Struct
>
>   layout  :os_version_info_size, :int,
>             :major_version, :int,
>             :minor_version, :int,
>             :build_number, :int,
>             :platform_id, :int,
>             :csdv_version, :buffer_out
>
> end
>
> ptr = FFI::MemoryPointer.new(:pointer, 128)
> osversioninfo = OSVersionInfo.new
> osversioninfo[:csdv_version] = ptr # line 106
> osversioninfo[:os_version_info_size] = OSVersionInfo.size
> get_version_ex(osversioninfo)
> p osversioninfo[:major_version]
> ---------------------------------------------------------
> I get this error:
> ---------------------------------------------------------
> system_info.rb:106:in `put': put not supported for
> FFI::StructLayout::Field (ArgumentError)
>         from system_info.rb:106:in `[]='
>         from system_info.rb:106:in `test_version'
>         from system_info.rb:117:in `<main>'
> ---------------------------------------------------------
> I tried it without the MemoryPointer:
> ---------------------------------------------------------
> osversioninfo = OSVersionInfo.new
> osversioninfo[:os_version_info_size] = OSVersionInfo.size
> get_version_ex(osversioninfo)
> p osversioninfo[:major_version] #=> 0
> ---------------------------------------------------------
> That code doesn't thorw an error, but the function call fails - the
> line starting with "p" should print out 6 on my Vista machine.
> How can this be done?
>
> The second question is a simple one: Where do I find a quick example
> of how to use the FFI::Union class? The wiki just states this:> The actual Windows INPUT struct contains an anonymous union member with MOUSEINPUT, KEYBDINPUT,
> > and HARDWAREINPUT members. As the MOUSEINPUT struct is the largest of these members, we can get
> > away with the hacky InputEvent FFI union definition for example purposes.
>
> So, what to do if I haven't an "example purpose"?
>
> ruby -v: ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-mingw32]
> OS: Windows Vista SP2
>
> Marvin