Skip to main content
gamedev.net
🔒 Locked

Using handles acceptable?

Started by SirLuthor 9 replies 950+ views
Original Post
SirLuthor
SirLuthor
Good even fine people! A question, if I may be so bold! Anyway, I'm working on an engine as some of you may know, and I've lately been thinking of how I'm going to do client to DLL interaction, that is, how are people going to use my engine. Now, since it is in an explicitly linked DLL, it becomes odious to export classes, a load of extra hassle that I'm sure few people want. However, I was thinking, would it be too slow to do things as the Win32 API does it, that is, returning handles, that are passed to functions, and used as lookup values in a table to determine the object in question? Added benefits of this are of course that it can be used with straight C as well, if done properly, and, it keeps things nice and simple. However, I'm greatly fearing that it will be terribly slow, having to lookup an object in a table that could be large, every time something is used. So I really have no clue which one I should go with. So what are your opinions/experiences? Is it possible with handles, or should I wrap those classes, come hell or high water? It would also help if people could cite examples of commercially accepted engines that use whatever method. Much obliged.
Free speech for the living, dead men tell no tales,Your laughing finger will never point again...Omerta!Sing for me now!
SiCrane
SiCrane
You know, you can just use pointers as your handles. Cast the pointers to your handle type and back to a pointer type. That way you don't need to index into a table.
SirLuthor
SirLuthor
True, but you lose type-safety to some degree, not so? Or at the very least, safety.
Free speech for the living, dead men tell no tales,Your laughing finger will never point again...Omerta!Sing for me now!
SiCrane
SiCrane
It's how many of the Windows handles work. If you want you can make the handles pointers to undefined types (types undefined in the code the client sees that is). However, if users get handled pointers they might think they need to do pointer like things to them like delete.
SirLuthor
SirLuthor
Hehehe, a good point. Thanks for clearing that up, I don't know why I didn't think of that my self, to use the address as the handle [grin]
Free speech for the living, dead men tell no tales,Your laughing finger will never point again...Omerta!Sing for me now!
SiCrane
SiCrane
Handles are an abstraction. They may be disguised pointers, or the may be indexes into a table, or they may be something else entirely. The point is the client of the API doesn't know what they are and doesn't actually care. This allows the API to be used in languages that are not pointer aware like Visual Basic, and allows the implementation of the API to change representation behind the scenes without bothering the client code. For example some handles that were disguised pointers in Windows 95 were indicies into tables in NT 4.
outRider
outRider
They're also more useful in C than in C++, they hide data and force you to take action through functions, roughly similar to encapsulation provided by C++ classes and structs.

Let's take Win32, you get an HWND, which may actually be a pointer to a struct, but you can't manipulate the data in that struct because you have no information on the struct whatsoever. If you want to do something with the HWND you'll have to use a function. The function probably just casts it to a struct pointer and does whatever it needs to do with it, and all you know is that it got done. Very useful in a C environment.
multisample
multisample


Another reason for handles is so the "server"/engine side can relocate the objects at will and the handle never changes. Handles allow the "server" side to abstract any and all access or location information. Some console games use handles so that they can defrag memory when needed and not effect the client game code. The downside is it can take more memory accesses/clock cycles to use the handle. Whether to use them or not depends on the requirements for your application. Just weigh the gains vs tradeoffs and decide based on that. There is no "better" general solution.

markr
markr
Sounds like a way complicated scheme to solve a problem which shouldn't exist.

If you can't pass pointers to objects to / from DLL function calls, you shouldn't be using a DLL - it's obviously not a usable mechanism.

The problem should not exist. Don't make an unwieldy solution for a problem which should not exist.

Mark
Jan Wassenberg
Jan Wassenberg
Quote:
True, but you lose type-safety to some degree, not so? Or at the very least, safety.

Indeed - passing back pointers is very dangerous, because some fool might actually access your data (it being convenient at the time).
Note: Win9x used pointers to TEB as thread handle, but obfuscated them with an XOR value generated at boot-time.

Quote:
It's how many of the Windows handles work.

Clarification: kernel handles (anything you pass to CloseHandle) all go through the Windows handle manager. Those that do not are the exception and suffer for it :)

On PCs, dereferencing handles is not an issue - it's just a mul+add. Storing all resource data in an array has some advantages anyway:
- locality
- avoid tons of allocs by reusing array entries
- array can be expanded (without changing address) with a VirtualAlloc reserve-max-size / commit-needed-size scheme.
- entire array can be locked-down, preventing write access. Useful in debug builds to see who is corrupting your memory.
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.