Home > front end >  Why the parameter syntax operator "[" is used in this case ? As Like" "['i&
Why the parameter syntax operator "[" is used in this case ? As Like" "['i&

Time:09-09

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 [' ']?

CodePudding user response:

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)

CodePudding user response:

You might want to use Fiddle as a more recent alternative. Its 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