Why the parameter syntax operator "[" is used in this case ? As Like" "['i']" " I am using as a script for RGSS, RPG Maker XP with win32api and ruby

Viewed 53

In this case:

x = Win32API.new("user32","GetAsyncKeyState",['i'],'i').call(0x01)

I understood the code as a whole, it returns a value when the left mouse button is clicked. However, I would like to know why the programmer used this symbol [ like that ['i'] as a parameter. I know that the parameter is for the type of import and that the i means integer, but why the use of the [' ']?

2 Answers

The 3rd parameter of Win32API.new() is an array of types, as a function can have more than 1 input parameter.

GetAsyncKeyState() has 1 input parameter which is an integer, so the ['i'] is an array of 1 type to reflect that fact.

The subsequent 'i' is not an array, because a function can have only 1 return value. In this case, GetAsyncKeyState() returns an integer as output.

This is mentioned in the book "Ruby in a Nutshell" by Yukihiro Matsumoto:

Win32API::new(dll, proc, import, export)

Returns the object representing the Win32API function specified by proc name in dll, which has the signature specified by import and export. import is an array of strings denoting types. export is a type specifying string.

Perhaps the below example would make it more clear to you:

Calling Windows APIs

int WINAPI MessageBox(
   _In_opt_ HWND    hwnd,
   _In_opt_ LPCTSTR lpText,
   _In_opt_ LPCTSTR lpCaption,
   _In_     UINT    uType
);

...

require "Win32API"

title = "Rubyfu!"
message = "You've called the Windows API Successfully! \n\n@Rubyfu"

api = Win32API.new('user32', 'MessageBoxA', ['L', 'P', 'P', 'L'], 'I')
api.call(0, message, title, 0)

Note that Win32API was deprecated with Ruby 1.9.1. The current version is merely a wrapper around Fiddle and you are advised to use Fiddle directly as a more recent alternative.

The Fiddle::Import module provides a simple DSL to declare the C functions and additional types like SHORT inside a Ruby module, e.g.:

require 'fiddle/import'

module User32
  extend Fiddle::Importer
  dlload 'user32'
  typealias 'SHORT', 'short'
  extern 'SHORT GetAsyncKeyState(int)'
end

Afterwards, you can call the C function as a Ruby class method of that module:

x = User32.GetAsyncKeyState(1)
Related