Unique ID from Delegate

I’m storing a dictionary of delegates. I want to be able to convert a “weakAddressOf” delegate to a unique string identifier:

dim p as ptr = d //d is my delegate dim mb as MemoryBlock = p dim id as string = Crypto.SHA256(mb)
This code blows up however. Is there a better/different way to get a unique string id from a delegate?

If you don’t find a solution, a container class should work. Hold the delegate and generate your own UUID.

This line is likely problematic since it trie to set the MB to be based at the PTR’s address

dim mb as MemoryBlock = p

but I think you want the mb to contain the address (No ?)

dim mb as new MemoryBlock( 8 ) //  8 because thats SizeOfPtr 
mb.Ptr(0) = p

and now run crypto.sha256 on that

more or less you just get the address of the delegate which is unique but only applies to THIS running instance of the app as I dont think there’s any assurance the delegate will be located in the same place in memory on the next run

How about store the delegate in a Variant and use Variant.Hash?

Wow that’s even simpler although the sha256 is longer than the integer so I wonder if it is safer in avoiding collisions…

guess it depends on what the intent is for this

And why SHA256 to blow up a 64bit value to 256 bit?

So are you saying there’s no advantage over the variant hash. My main goal is to avoid collisions

The ptr itself is a pretty unique 32/64-bit value already.

Variant.Hash reduces that to 32/64 bit integer.
SHA256 may do a 256-bit integer.

It is unlikely, but possible that you free the data and new data get the same ptr assigned.
Doing hashes will not make this more unlikely.
And if you keep objects around, the ptr is a perfect value already.

Christian is correct. The “algorithm” to get a value from such address, using less bits, and avoiding collisions with such address, is just getting the address by itself. But… depending on the OS used managing memory at a low level, the frameworks managing the memory at a high level, the operations done after you collect that address, I’m not sure if some objects will stay immutable where they are, all the time. As Xojo does not use a background garbage collection with reallocation, maybe they will.

The pointers stay the same until memory is freed, where it could be reused.
But it’s unlikely that the same address will be reused for the same thing as any little allocation in-between may just use that address for something else.

I asked previously what the intended purpose was since its unlikely that the code will be loaded at the same location next run.
Usually with a has you want some sort of stability - hashing the same thing multiple times gives you the same has each time.
This wont have that characterstic because of how memory is used by a running application.

I’m using it in a WebApplication. I’m thinking overlaps will be rare because the unique gets put into a dictionary tied to a specific web session. I’m wrapping javascript libraries and I need to be able to pass server delegates to the client side that get called via javascript. I’m using the WebSDK with a dictionary to store the session’s delegates and trigger them when the client side needs to. This process works - I just wanted to make sure I can reference the delegates with unique id. I have to call XojoTriggerServer in javascript and pass my WebSDKControlId, “TriggerDelegate”, and the id of the delegate.

Another related question. I’m using weakAddressOf for the delegates and I periodically want to “clean up” the dictionary of delegates. But even after I close a WebView with the instance of the method I made a delegate of it seems like the dictionary doesn’t see the delegate as nil. But when I call the delegate it throws a nilObjectException. Is there a way to properly clean these up if the delegate no longer tied to an existing control?

weak address of is a pain because you cant detect things - exactly like you’re describing

there’s a long standing bug report about this - <https://xojo.com/issue/26060>

what you might need to do is store BOTH a weakaddressof and a weakref to the instance that holds the delegate
then you can detect the weakref is nil and react accordingly and not invoke the weak delegate