Skip to content

Function Prototypes

djberg96 edited this page Apr 6, 2012 · 1 revision

Prototype Characters

There are 5 function prototype characters. Here's what they are, what they represent and when you should use them:

  • S => String. Used for __in parameters only where the parameter is some form of const char*, LPCTSTR, etc.
  • P => Pointer. Used for most pointers, including __in or __inout string buffers.
  • L => Long. Used for long data types, including signed or unsigned, longlong, etc.
  • I => Integer. Used for integer data types, including signed or unsigned.
  • V => Void. Used for void data types.
  • K => A special type of pointer, used for function callbacks.

Pointer or Pointer Address?

In some cases you can use either a pointer (P) or a long (L) interchangeably in a function prototype. Typically this is when you're dealing with string pointers where you can use either a string buffer or an address. For example, the memcpy function prototype looks like this:

void * memcpy (void* destination, const void* source, size_t num);

This function could be declared in any one of four ways.

memcpy1 = Win32::API.new('memcpy', 'PLL', 'P', 'msvcrt')
memcpy2 = Win32::API.new('memcpy', 'LPL', 'P', 'msvcrt')
memcpy3 = Win32::API.new('memcpy', 'LLL', 'P', 'msvcrt')
memcpy4 = Win32::API.new('memcpy', 'PPL', 'P', 'msvcrt')

Here are a couple examples of usage:

str = "hello"
buf = 0.chr * 10
ptr = [str].pack('p*').unpack('L').first # This is how you get a string address

memcpy1.call(buf, ptr, str.size)
p buf.strip

memcpy4.call(buf, str, str.size)
p buf.strip

Caveat

Getting a string's address is possible in MRI Ruby because it uses a C implementation. This is not something you normally do, and it may not work in other implementations of Ruby, such as JRuby, because it uses Java for its implementation, and does not use pointers behind the scenes.

Clone this wiki locally