Advertisement

The Guise of COM

Started by April 03, 2001 12:20 AM
4 comments, last by Shannon Barber 23 years, 10 months ago
This has been brewing in my head for a while now, and I need to vent At first I got swept up in how cool it would be to write some COM object that work together, like the Dx ones, that you could create and use in C++/VB/Delphi/Java/VB Script/etc... I wrote a test interface that could be used in all of these (it returned the integer 8). If you want to do anything much more complicated than that, kiss the language neutrality good-bye. VB, Threads & types: VB does not support unsigned types. That''s why Dx blows on VB. VB also does not support multiple threads - kiss my bad-ass free-threaded design good-bye. Of all the reasons to hate VB (and there are many ) these two are intolerable . Rumor is that VB7 will support threads... VB6 might support signle-thread apartments now, but a-mon-avis, those are a snot above useless. I didn''t bother checking the scripting langauges, I assumed that they suck too. Strings: You''re suppose to use BSTR''s for your strings - so that VB and manipulate them, and so you don''t have to worry about who allocates them or deallocates them as windows API calls take care of it. A big problem with this kind of thing is who allocates the memory, and who frees it - more so for cross-language apps. They''re kindov a pain, but well worth it to avoid the reallocation problems. So BSTRs get a thumbs-up (I just wish there was an ansi version to go with the wide.) Arrays: The COM spec calls for all arrays to be passed using safe arrays. Again for VB compatibility more than anything else. But it''s not a bad idea (neccessary I''d say) to send data along with the data pointer describing what''s pointed at. SafeArrays solve the same allocation problem that BSTRs do as well - either the app or the coclass can allocate, reallocate, or free the array data because they all use the same system calls to create the array. This worked remarkable well in VB (so long as you didn''t use and unsigned types, strings, or a couple of other ''COM'' data types that VB doesn''t support.) I even managed to get an array of UDTs (User Defined Types) to work. However, Delphi does not expose the SafeArrayxxxEx funtcions needed to create, destroy, and manipulate arrays of UDTs (as of v5 SP1). I imagine that you could load the dll yourself and call the functions, but I left wondering why Borland didn''t include them - makes me think it got hard... I decided to drop safearray''s and forget about any cross-language support beyond Delphi - Delphi can work with ''raw'' pointers, so screw any language that can''t. All that was bad enough, but it takes 4 second to create the initial IDirectDAQ object. I cache the CDirectDAQDevice''s (singletons) so that they only need to be constructed once - they take about 3 seconds to construct. I was expecting ~300ms (it does have to load a dll). The registry lookup seems to obliterate performance. I have to agree with Carmack that COM sucks (though for different reasons).
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
From what you''ve said, I take it that you can''t use COM properly in Java as well since you don''t have pointers in Java?

Anyway, I remember you reccommending COM to lots of people on this board until quite recently. Does that mean you''re not going to reccommend it anymore ?

On a side note, how do you export a class to a DLL? I haven''t had much luck in that.
==========================================In a team, you either lead, follow or GET OUT OF THE WAY.
Advertisement
quote:
Original post by NuffSaid

On a side note, how do you export a class to a DLL? I haven''t had much luck in that.


Depends on what you use DLLs for. If you are loading DLLs at runtime then you''ll need to make sure that all classes in your DLL are derived from a class (abstract or otherwise) in your game. Then you can get around this problem by using the Factory Pattern.

What I do is require all plugin DLL''s to have a GetInterface function. All this function returns is an instance of the DLLs Factory class. I then use this Factory class to create and return instances of all classes in that DLL. In my game I just create a pointer of the base type and set that equal to the instance the Factory class returns.


- Houdini
- Houdini
COM sounds good in theory, however you have to strip away most of the language improvements of the last 20 years (i.e., exceptions, inlining, cool little user-defined types, return values for data, references) for the interface. The interface''s inability to use these features tends to discourage their use in the implementation.

I would like to see a simple COM-like spec implemented in C++ and used only by C++ code. You could use all the features of the language and see how component-oriented programming would work without the klunky COM code. You would need a small Windows DLL and registry key which would handle installation and instantiation. A small static lib and header file could contain the base classes and load/unload the main DLL, which would handle the instantiation requests and so forth.

Imagine components that can:

1. Freely use exceptions instead of HRESULTs.
2. Freely use multiple threads.
3. Operate faster, because the caller doesn''t have to check return values.
4. Start more quickly, because of a less complex system.
5. Transparently use automatic interfaces that maintain their own reference counts.

Perhaps I''ll write up something like this now?
COM works in Java (as well VB) by using references, sorta. There''s an class called ''object'' or ''.ms.com.object'' that you can create IUnknown interface pointers with.

quote:
- null_pointer
I would like to see a simple COM-like spec implemented in C++ and used only by C++ code.


You kinda do that with COM. You make a COM mediator object, like IDirect3D7 or etc..., and then it can directly instance other objects and return thier interface pointers. So it reduces the COM creation overhead to one object. I think everything would have to live in the same dll though.
My plan for my game is to skip the COM entirely but draw from the IInterface methodlogy.

Once you make a dll, you are 7 functions away from a COM Object. 4 are dll exports, DllCanUnloadNow, DllGetClassObject, DllRegisterServer, DllUnregisterServer; and three are required class methods, AddRef, Release, & QueryInterface. You object needs to derive from IUnkwown, and you''re done. If you use the ATL wizard, it takes 4 or 5 mouse clicks. (When you build it even registers the object for you.) You don''t need a ''dual'' interface ie derive from IDispatch, unless you want to use the object from a scripting language.




Magmai Kai Holmlor
- The disgruntled & disillusioned
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Hey null_pointer, your wish list basically asks for what .NET will provide via MSIL/EE.

Magmai, VB 5 supported STA and MTA but Microsoft changed all that with VB6 which only supports STA. Still, that doesn''t mean you can''t develop a free-threaded (MTA) ATL/C++ component and interact with VB. You''ll only run into problems, like I did, if you start passing GUI objects to a free-threaded component that modifies the components directly - especially if done from a different thread.

VB.NET (VB 7) will support free-threading which is really cool. Couple that with new error handling, better way of defining "classes" (interfaces), WinForms etc and I may stop using C++ for GUI development all together. I''ll probably still use C# for server-side component development though.

Dire Wolf
direwolf@digitalfiends.com

Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com

This topic is closed to new replies.

Advertisement