Subject: [ruby-ffi] Arrays in Structs and Unions |
From: Quintus |
Date: 2/4/10 1:21 PM |
To: ruby-ffi |
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;
----------------------------------------------------
( From http://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