It sounds like you could simply use the pointer value as the result of a "hash" then map it by applying a modulo operation based on the size of the hash array.
For instance, if your hash array is 101 (a prime number) then the hash key will be <pointer value> mod 101. Simple and very fast. Also, as long as the array has space for about 120% the number of elements as there are pointers you intend to "hash", the number of collisions should be small.
Lastly, to eliminate the non-portable message, if your hash function overlays a DWORD or qword on top of the pointer parameter, using an "absolute" clause (use a {$ifdef WIN32/64} to control the "absolute" then there won't be any warning message.
something along the lines of (pseudocode):
function Hash(p : pointer) : DWORD;
{$ifdef WIN32}var v : DWORD absolute p; {$else} var v : qword absolute p; {$endif}
begin
{ NOTE: < the number of array elements> below could be a global, a constant or }
{ another parameter, your choice }
result := v mod <number of array elements>;
end;
HTH.
ETA:
Actually you don't even need the {$ifdef}. You could simply do:
var
v : ptruint absolute p;
Additionally, the hash function is so simple it could be made inline.
ETA2:
the above declaration of "v" will also work to eliminate the compiler message in the code snippet you presented.
i.e,