|
May be ur not getting me or I explain not clearly.
Type safety is not what u have meant, please refer [^]
say, int function(int *) expects int * while int function (void *) is undefined.
that is why strongly typed languages uses type system
definition of void in msdn
The void type describes an empty set of values. No variable of type void can be specified — it is used primarily to declare functions that return no values or to declare generic pointers to untyped or arbitrarily typed data.
CoCreateInstance return pointer to IUnknown, but it is not type restricted to store in pointer to int. Actually to tackle this situation using C++ template is what george discussing with the use of IComPtr.
Matthew Faithfull wrote: hich will be overwritten by the CoCreateInstance call with an IUnknown pointer
not necessary. a pointer to object derived from IUnknown not pointer to IUnknown.
both r different. as a side note COM is binary standard it is not restricting to derive from IUnknown.
Question is not related to what CoCreateInstance returns, but is it type safe,
IX *pIX = NULL;
CoCreateInstance(..., IID_IY, &pIX); // not type safe, programming mistake not caught by typesafe compiler.
here trying to get interface to IX, but IID for IY, if COM interface for IY exist then expected IX interface is not valid.
modified on Monday, February 11, 2008 8:51 AM
|
|
|
|
|
I understand void pointers and the concept of type safety but it is not a problem in this case as long as the server obeys the rules of COM it cannot cause a well written client a problem. The traditional problem with returning a void* ( you can't be sure what it really points to ) is removed because it always points to IUnknown.
The only way the client can screw things up is to pass the address of something that sould not be overwritten in the ppv parameter and that would be plain stupid and no fault of the server or the function spec of CoCreateInstance. Your example may be incorrect sematically but it will compile and work there is no type safety issue.
Consider typeof (&(int*)) == typeof(&(SComeInterface)). Or in English, an address is and address is an address as long as we all agree we're talking 32bit addresses.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Matthew Faithfull wrote: I understand void pointers and the concept of type safety
ohh, my explaination is ok i think
Matthew Faithfull wrote: in this case as long as the server obeys the rules
with the context of type safe, here who talks about the COM Server, COM Client Sample is given in george's post. And generally if no body makes mistake with data type handling, type system (int, float, ...) and a strongly typed languages is not required.
Matthew Faithfull wrote: Or in English, an address is and address is an address as long as we all agree we're talking 32bit addresses.
yes, sure address is address, But calling interface function of IX with IX * with the address of IY * is not valid.
Matthew Faithfull wrote: Your example may be incorrect sematically but it will compile and work there is no type safety issue.
to reduce semantically incorrect situation, type safety comes into picture. That is; it won't compile, if you pass IY * in place of IX *.
|
|
|
|
|
COM has to be general, it provides a binary standard available also to languages that are no strong typed.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
please make of use of Strong typed feature of language, which supports it.
|
|
|
|
|
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
I mean not while implementing COM, while using it in a strong typed language.
|
|
|
|
|
And what was your advice about?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
not advice, suggestion
|
|
|
|
|
And your suggestion was?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Rajkumar R wrote: But calling interface function of IX with IX * with the address of IY * is not valid.
It is when both are gaurenteed to be derived from IUnknown and by the rules of COM you can only call the members of IUnknown until you have queired the validity of the interface you really want by calling QueryInterface. A properly written client will not call any method other than IUnknown methods until it has a result from QueryInterface so you can go right ahead and use your IX* or IY*, when you QueryInterface for the interface you actaully want the COM server can say NO, then it is invalid to make the call you want. The address of IX* and the address of IY* are interchangable up to this point, they are both treated as type IUnknown** regardless and this does not cause any issues other than possible programmer confusion. It is type correct as far as any machine can possibly tell.
Rajkumar R wrote: it won't compile, if you pass IY * in place of IX *.
If the compiler did that then it would not let you pass a CMyDocument* to a function taking a CDocument* that only operates on CObject members and that would make life very difficult
You might want to research into the Ada language if you want to live with those sort of restrictions.
Nothing is exactly what it seems but everything with seems can be unpicked.
modified on Monday, February 11, 2008 9:39 AM
|
|
|
|
|
Matthew Faithfull wrote: The address of IX* and the address of IY* are interchangable up to this point
COM needs QueryInterface basically address of IX and IY may not be the same.
Matthew Faithfull wrote: CMyDocument* to a function taking a CDocument*
but compilers says error when CMyDocument2 * is passed to a function taking CMyDocument1 * ,even both derived one level from CMyDocument.
And also, if the function is taking CDocument, it is expected that the function is expected to work on CDocument interfaces only even though it is the object of CMyDocument, So I think life is not difficult. Even if it needs to operate on CMyDocument, C++ provides typesafe dynamic_cast.
modified on Monday, February 11, 2008 10:13 AM
|
|
|
|
|
Rajkumar R wrote: address of IX and IY may not be the same.
It doesn't matter, as long as both are valid 4 byte parameters an address is an address is an address.
Rajkumar R wrote: but compilers says error when CMyDocument2 * is passed to a function taking CMyDocument1 * ,even both derived one level from CMyDocument.
Not if the function takes CMyDocument*, which is the case we're dealing with here.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Matthew Faithfull wrote: Not if the function takes CMyDocument*, which is the case we're dealing with here.
that is why i mentioned type safe dynamic_cast for ur example.
and also your example doesnot match directly to the george sample of IX and IY derived from IUnknown and I matched with CMyDocument2 and CMyDocument1 derived from CDocument.
modified on Monday, February 11, 2008 10:45 AM
|
|
|
|
|
Rajkumar R wrote: your example doesnot match directly
The principle is exactly the same. If a function has an [out] parameter of type CMyDocument*. In other words it takes in the address of a CMyDocument pointer, doesn't care what the value of the pointer is and overwrites it with a valid CMyDocument* pointer then it is perfectly typesafe and valid to pass that function the address of a CMyDocument1* or the address of a CMyDocument2* because these ARE CMydocument* pointers or a void* where this is a valid address for a CMyDocument* to be written into. The only restriction is that after the call you treat the pointer as a CMyDocument* not a CMyDocument1* or a CMyDocuemt2* until you have established whether it really does point ot a derived type or not. Remember all pointers are the same size and the address of a pointer is exactly the same thing as a void* anyway, slapping a type on it, which may not be the type returned, is no more or less type safe. You still have to follow the same steps on return to ensure you've got what you intended except now the code gives you a false sense of security because it looks like you're gaurenteed to get the type you asked for when you're not.
It may seem silly to labour the point but it is important not to try and impose C++ concepts unaltered onto COM. To do COM well you need to understand the changes in the way of thinking that it brings.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Whenever sombody using base class pointer to get a derived class one they need to use type safe dynamic_cast operator, so no question of issue on C++ type safety,
And in COM, the use of __uuidof() keyword reduce the possibility of mismatch UUID and a interface type. And again wrapper classes CComPtr, ... helps more in reducing programming mistakes although syntactically correct.
|
|
|
|
|
Rajkumar R wrote: Whenever sombody using base class pointer to get a derived class one they need to use type safe dynamic_cast operator
Except in COM where this is the wrong way and QueryInterface is the right way.
Rajkumar R wrote: And in COM, the use of __uuidof() keyword reduce the possibility of mismatch UUID and a interface type. And again wrapper classes CComPtr, ... helps more in reducing programming mistakes although syntactically correct.
Agreed. There's no problem with using wrapper classes and C++ mechanics to make it easier to write correct code but when COM is involved COM rules have to override normal C++ practice. It's what makes COM tricky but it's also what allows it to reach beyond C++ and has made it vital to all kinds of interoperation in the .NET Windows world and beyond.
As my DevelopMentor T shirt says, COM is Love
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Matthew Faithfull wrote: Except in COM
I did't meant using dynamic_cast on COM
Matthew Faithfull wrote: It's what makes COM tricky
non sense, it has nothing to do with COM, only C++ helper
Matthew Faithfull wrote: DevelopMentor
so u need to say explicitly u r great
|
|
|
|
|
Matthew Faithfull wrote: Anyway COM is typesafe
While COM does enforce type safety after a fashion ( as you pointed out as long as everyone follows the rules), it certainly does not provide a compile time type safety mechanism. Compile time mechanisms as in Templates and Generics are just not there in COM, period.
led mike
|
|
|
|
|
Exactly, the kind of aggressive type safety checking being proposed in this thread would probably prevent COM from working at all. When in COM do as COM does, get your type safety by proper use of QueryInterface not by relying on a compiler which may not even work on the same operating system as the component you're trying to create an instance of.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Matthew Faithfull wrote: would probably prevent COM from working at all
non sense, __uuidof() a compile time keyword, CComPtr, ... are inline functions and they do no harm to COM insteads helps in increasing development and decreases mistakes.
Matthew Faithfull wrote: not by relying on a compiler
As far as this is VC++ message board,no issues.
Matthew Faithfull wrote: which may not even work on the same operating system
non sense, OS dependencies are not there using CComPtr, over MS COM
|
|
|
|
|
And how does __uuidof provides strong typed feature?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
if iam wrong pls correct, making use of __uuidof(), CComPtr class makes type safe.
|
|
|
|
|
Rajkumar R wrote: making use of __uuidof(), CComPtr class makes type safe.
I don't think so. Anyway my sign (Iain Clarke's sentence) holds still.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
thanks i left my sign blank for this
Any way why u don't think so, CComPtr reduces the mismatch between REFIID and ppv that is the question,
I found these as technical discussion, I take this oppurtunity to get more knowledge. I Consider and take care not to be arrogant if so.
|
|
|
|