Pointer - Object Oriented Memory Pointers in Pure Perl
use Pointer; use Pointer::int; use Pointer::sv; # Hello, world the hard way print pointer->of_scalar("Hello, world")->get_pointer->get_pointer->get_string; # Test to see if a scalar is a string print "It's a string!" if pointer('sv')->of_scalar('12345')->sv_flags & SVf_POK; # Hex dump of the first 3 words of the SV for $/ print "> $_\n" for pointer('int')->of_scalar($/)->get_hex(3); # Print 5 integers 10 integers away from the address of $$ print((pointer('int')->of_scalar($$) + 10)->get(5));
This module allows you to create Perl objects that emulate C pointers. You can use them to read and explore the memory of your Perl process.
Pointer.pm (and every subclass) exports a function called
pointer that returns a new pointer object. Each object has a type like (void, int, long, sv). Support for each pointer type is written as a subclass of Pointer.pm. Pointer.pm itself is for type
void. To create a pointer to a long integer, do:
use Pointer::long; my $p = pointer('long');
Your new pointer is not pointing to anything yet. One way to put an address into the pointer is directly, like this:
Another way is to point it at an existing scalar like this:
Both of these methods return the pointer so that you can chain other methods onto them:
my $int = $p->of_scalar($foo)->get;
get method returns whatever the pointer points to. Since
$p is an integer pointer, this call returns an integer. The
get method takes an optional number as an argument, which indicates the number of values to get.
Pointer pointers honor pointer arithmetic. If you add or subtract a number to a pointer, the result is another pointer. As in C pointer arithmetic, the number of bytes added to the address depends on the size of the type represented by the pointer.
my $p1 = pointer('long')->of_scalar($foo); my $p2 = $p1 - 5;
is the same as:
my $p1 = pointer('long')->of_scalar($foo); my $p2 = pointer('long')->address($p1->address - 5 * $p1->sizeof);
The following methods are available for all pointers:
Sets the address of a pointer to a specific integer. Returns the pointer object for chaining calls.
Sets the address of a pointer to the address a Perl scalar or SV. Returns the pointer object for chaining calls.
Returns the memory address of the pointer as an integer.
Returns the address as a hexadecimal string.
Returns the type of the pointer.
Returns the size (in bytes) of whatever type of data is pointed to.
Get the item(s) pointed to by the pointer. This function takes a numeric argument indicating how many items you want to retrieve. The function returns a list of the items requested.
get, but returns the items in hexadeciaml.
Returns the null terminated string pointed to by the pointer.
If your pointer points to a pointer address, this call will take the pointer address, and return a new pointer object that contains it. You can pass in the type of the new pointer. The default type is a void pointer.
Returns the raw byte content pointed to by the pointer. You will need to unpack the raw data yourself. Takes an argument indicating how many bytes to return.
Pointer.pm was made to be subclassed. Every type of pointer is a subclass. See the modules: Pointer::int, Pointer::long and Pointer::sv for examples.
Pointers are tricky beasts, and there are myriad platform issues. At this point, Pointer.pm is but a naive attempt at a novel idea. Hopefully it can be fleshed out into a robust and serious module.
Support for pointers to structs is minimal, but is a primary design goal. Pointer ships with a subclass for the sv struct as an example. Expect better struct support in a future release.
If you have a good feel for C pointers, and grok where I am trying to go with this module, please send me an email with your good ideas.
Brian Ingerson <INGY@cpan.org>
Copyright (c) 2004. Brian Ingerson. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.