dual interface
-
Scripts client use only
VARIANT
datatype only viaIDispatch
. Of course, you know, this is going on my arrogant... :)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
[My articles]Thanks CPallini, I did some search but find no results. Do you have any documents referrals which describes whether script language could use TLB or not? regards, George
-
Thanks CPallini, I did some search but find no results. Do you have any documents referrals which describes whether script language could use TLB or not? regards, George
Oh, well no. But I'm pretty sure: VBScript & JScript (I'm not talkingt about the
.NET
one) have onlyVARIANT
datatype and can only accessCOM
components viaIDispatch
. You may have a look toVBScript
orJScript
reference documentation onMSDN
. :)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
[My articles] -
Oh, well no. But I'm pretty sure: VBScript & JScript (I'm not talkingt about the
.NET
one) have onlyVARIANT
datatype and can only accessCOM
components viaIDispatch
. You may have a look toVBScript
orJScript
reference documentation onMSDN
. :)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
[My articles]Thanks for your long help, CPallini! Let us continue to discuss here. :-) http://www.codeproject.com/script/Forums/View.aspx?fid=1647&msg=2725088[^] regards, George
-
Thanks Scott, 1. Why "you are developing a COM component that you are going to make publicly available to other developers" as you mentioned, I must expose IDisaptch? I could expose vtable only and let them use C++. :-) Any comments or any important points which I missed in my above statements? 2. I further question. If we want to support IDispatch, all types in methods' parameter/return value must be auomtation compatible? If yes, why? :-) regards, George
Yes, on point number 1...You ONLY have to support IDispatch if you want scripting languages or other languages that use late binding to be able to use to your COM server component. Of course, this is very often the case these days with so many COM components being written to plug into web sites and be called from VB script, Java script, etc. I'm sorry I should have made this more clear. So, you CAN have a COM component publicly available that does NOT support IDispatch, but it will need to be linked with the client program at compile (build) time. On point 2: YES, all parameter/return values MUST be automation compatible. Basically, this means that everything must be VARIANT, BSTR, long integer, etc. Why? Because COM is a defined standard that all programming languages that wish to be COM compliant must adhere to if they wish to interface with each other, and IDispatch is a defined interface within the standard. If you wish to use much of the automation linkage already put into place by Microsoft, and the COM subsystem (also implemented by Microsoft via Windows), you'll have to adhere to the standards of the subsystem components. For example, of you try to pass a "C-style" string from a C++ program to a VB program through a COM interface, the VB program will probably crash because it doesn't "understand" the structure of a C-style string. Incidentally, I had to read two or three books on COM and diligently work the examples before I got it figured out. I tried using ATL and the Visual Studio wizards to create my COM components, but quickly gave up on this because it was very inflexible when I wanted to make additions or changes to my COM classes. I ended up hand-building, from scratch, all of my COM components, but now I have a library of components for use in my applications. Scott :)
-
Yes, on point number 1...You ONLY have to support IDispatch if you want scripting languages or other languages that use late binding to be able to use to your COM server component. Of course, this is very often the case these days with so many COM components being written to plug into web sites and be called from VB script, Java script, etc. I'm sorry I should have made this more clear. So, you CAN have a COM component publicly available that does NOT support IDispatch, but it will need to be linked with the client program at compile (build) time. On point 2: YES, all parameter/return values MUST be automation compatible. Basically, this means that everything must be VARIANT, BSTR, long integer, etc. Why? Because COM is a defined standard that all programming languages that wish to be COM compliant must adhere to if they wish to interface with each other, and IDispatch is a defined interface within the standard. If you wish to use much of the automation linkage already put into place by Microsoft, and the COM subsystem (also implemented by Microsoft via Windows), you'll have to adhere to the standards of the subsystem components. For example, of you try to pass a "C-style" string from a C++ program to a VB program through a COM interface, the VB program will probably crash because it doesn't "understand" the structure of a C-style string. Incidentally, I had to read two or three books on COM and diligently work the examples before I got it figured out. I tried using ATL and the Visual Studio wizards to create my COM components, but quickly gave up on this because it was very inflexible when I wanted to make additions or changes to my COM classes. I ended up hand-building, from scratch, all of my COM components, but now I have a library of components for use in my applications. Scott :)
Thanks Scott, Your answer is really great! Just want to clarify two things. 1. No matter who (I mean COM consumer) will use IDispatch interface, like C++/VB such advanced client or script client, all the parameter types and return value types we use IDispatch.Invoke to pass in/out should be VARIANT, correct? 2. My current confusion is, in IDL I have defined some customized data type (some struct) and in some methods I use such customized data type as input parameter or return value. If I want to support IDispatch.Invoke to consume the methods, could I use such customized data type either as input parameter or return value, even for advanced client C++/VB? :-) regards, George
-
Thanks Scott, Your answer is really great! Just want to clarify two things. 1. No matter who (I mean COM consumer) will use IDispatch interface, like C++/VB such advanced client or script client, all the parameter types and return value types we use IDispatch.Invoke to pass in/out should be VARIANT, correct? 2. My current confusion is, in IDL I have defined some customized data type (some struct) and in some methods I use such customized data type as input parameter or return value. If I want to support IDispatch.Invoke to consume the methods, could I use such customized data type either as input parameter or return value, even for advanced client C++/VB? :-) regards, George
- Well, not necessarily: for example, automation directly supports BSTR (b-strings) and 4-byte integer values (known as long integers in C++), BUT...to keep things more simple, I would recommend just using VARIANT for all of your parameters, as you suggest. If you study the VARIANT data type closely, you'll see that the VARIANT structure itself actually can hold many other data types. Its up to you to figure out what a VARIANT contains by looking at the '.vt' member of the structure. Also, if you're writing in VB, VB can automatically convert from VARIANT to other data types for you. I believe C# can do this also, although I haven't really dabbled in C# yet. If you're writing in C++, you can use the _variant_t class which provides many conversion operators (I use _variant_t all the time in my C++ code). 2) I wouldn't necessarily recommend using a custom data type through the IDispatch interface unless your ready to write "custom marshalling" routines. "Marshaling" is the process of packaging up your function calls and parameters, then passing them across process boundaries, and possibly even across machine boundaries if you are going to have a client on one machine invoke a COM server on another machine (which is another really cool thing to do with COM). Microsoft provides COM components that can performing the marshalling for you based on the information you have in your IDL. Is there a way you can take your custom data type and make it "look" like a standard type? For example, could your custom data type be type cast as a long integer (vt = VT_I4) and placed into a VARIANT for the function call? And then when the server gets the parameter value, it can type cast it again into whatever you need it to be? Scott
-
- Well, not necessarily: for example, automation directly supports BSTR (b-strings) and 4-byte integer values (known as long integers in C++), BUT...to keep things more simple, I would recommend just using VARIANT for all of your parameters, as you suggest. If you study the VARIANT data type closely, you'll see that the VARIANT structure itself actually can hold many other data types. Its up to you to figure out what a VARIANT contains by looking at the '.vt' member of the structure. Also, if you're writing in VB, VB can automatically convert from VARIANT to other data types for you. I believe C# can do this also, although I haven't really dabbled in C# yet. If you're writing in C++, you can use the _variant_t class which provides many conversion operators (I use _variant_t all the time in my C++ code). 2) I wouldn't necessarily recommend using a custom data type through the IDispatch interface unless your ready to write "custom marshalling" routines. "Marshaling" is the process of packaging up your function calls and parameters, then passing them across process boundaries, and possibly even across machine boundaries if you are going to have a client on one machine invoke a COM server on another machine (which is another really cool thing to do with COM). Microsoft provides COM components that can performing the marshalling for you based on the information you have in your IDL. Is there a way you can take your custom data type and make it "look" like a standard type? For example, could your custom data type be type cast as a long integer (vt = VT_I4) and placed into a VARIANT for the function call? And then when the server gets the parameter value, it can type cast it again into whatever you need it to be? Scott
Thanks Scott, I am always confused about two concepts. Automation compatible data type and VARIANT. Are they the same thing -- means if a data type could be represented by VARIANT, it is automation compatible? I did some study, and find seems VARIANT is not ole automation type? So, I am even confused. It is appreciated if you could clarify the relationship between ole automation data type and VARIANT. http://msdn.microsoft.com/en-us/library/aa367129%28VS.85%29.aspx[^] regards, George
-
Thanks Scott, I am always confused about two concepts. Automation compatible data type and VARIANT. Are they the same thing -- means if a data type could be represented by VARIANT, it is automation compatible? I did some study, and find seems VARIANT is not ole automation type? So, I am even confused. It is appreciated if you could clarify the relationship between ole automation data type and VARIANT. http://msdn.microsoft.com/en-us/library/aa367129%28VS.85%29.aspx[^] regards, George
Yes, the VARIANT data type IS "automation-compatible". In fact, the last time I checked, all parameters to the IDispatch interface HAD to be VARIANT. Thus, your phrase "means if a data type could be represented by VARIANT, it is automation compatible" is TRUE. I am not sure where you found something that indicates that a VARIANT is not an ole automation data type, but I think what you found is in error. There are other data types that can be marshalled between a COM client and a COM server, but you must use VARIANT with the IDispatch interface. Now, in the early days, "automation" was referred to as "OLE automation", where the acronym "OLE" meant "Object Linking and Embedding". This was a phrase that Microsoft used to describe its early techonologies for allowing their Office applications to work with each other. "OLE automation" was the precursor to COM. Later on, the VB team at Microsoft created the IDispatch interface, "OLE automation" bcame the foundation for "ActiveX" controls, people dropped the acronym "OLE" and simply started referring to "OLE automation" as just "automation", and the VB folks defined "automation" as meaning "a COM component that supports the IDispatch interface". These days, however, "automation" is generally accepted to mean simply "a software component that adheres to the COM specification", even if it does not support IDispatch. (Remember, a COM component does not have to support IDispatch.) Now, if you have ever programmed in VB, you know that you can use a variable without first declaring it. When you do this, VB automatically creates a variable of type...VARIANT. From the outset, VB is designed to be very flexible with regard to its data types, and because VB was both a compiled language AND a scripted language, the VARIANT data type was very convenient for passing data between software components that were bound at run-time (as with VB script). So, you can see why VARIANT is so important to the IDispatch interface. The VB folks at Microsoft had a strong influence on COM and the IDispatch interface. They were also very interested in the use of ActiveX controls (COM components) in VB form applications, and web-based applications using VB script. So, the moral of the story is: VARIANT is an "automation-compatible" data type, and is in fact probably the most commonly used data type for passing data between COM components. Now, there are other "automation" data types, for example BSTR. You can pass a BSTR between a COM client and a COM server. The "
-
Yes, the VARIANT data type IS "automation-compatible". In fact, the last time I checked, all parameters to the IDispatch interface HAD to be VARIANT. Thus, your phrase "means if a data type could be represented by VARIANT, it is automation compatible" is TRUE. I am not sure where you found something that indicates that a VARIANT is not an ole automation data type, but I think what you found is in error. There are other data types that can be marshalled between a COM client and a COM server, but you must use VARIANT with the IDispatch interface. Now, in the early days, "automation" was referred to as "OLE automation", where the acronym "OLE" meant "Object Linking and Embedding". This was a phrase that Microsoft used to describe its early techonologies for allowing their Office applications to work with each other. "OLE automation" was the precursor to COM. Later on, the VB team at Microsoft created the IDispatch interface, "OLE automation" bcame the foundation for "ActiveX" controls, people dropped the acronym "OLE" and simply started referring to "OLE automation" as just "automation", and the VB folks defined "automation" as meaning "a COM component that supports the IDispatch interface". These days, however, "automation" is generally accepted to mean simply "a software component that adheres to the COM specification", even if it does not support IDispatch. (Remember, a COM component does not have to support IDispatch.) Now, if you have ever programmed in VB, you know that you can use a variable without first declaring it. When you do this, VB automatically creates a variable of type...VARIANT. From the outset, VB is designed to be very flexible with regard to its data types, and because VB was both a compiled language AND a scripted language, the VARIANT data type was very convenient for passing data between software components that were bound at run-time (as with VB script). So, you can see why VARIANT is so important to the IDispatch interface. The VB folks at Microsoft had a strong influence on COM and the IDispatch interface. They were also very interested in the use of ActiveX controls (COM components) in VB form applications, and web-based applications using VB script. So, the moral of the story is: VARIANT is an "automation-compatible" data type, and is in fact probably the most commonly used data type for passing data between COM components. Now, there are other "automation" data types, for example BSTR. You can pass a BSTR between a COM client and a COM server. The "
Hi Scott, I am not sure why you say BSTR and long integer is not representable by VARIANT. In VARIANT we could represend BSTR and longlong. Here is a related link. Any comments or ideas? http://msdn.microsoft.com/en-us/library/ms221627.aspx[^] regards, George
-
Hi Scott, I am not sure why you say BSTR and long integer is not representable by VARIANT. In VARIANT we could represend BSTR and longlong. Here is a related link. Any comments or ideas? http://msdn.microsoft.com/en-us/library/ms221627.aspx[^] regards, George
Well, actually, I never said that. You are absolutely correct - you CAN represent BSTR and long integer in a VARIANT. BUT...you don't have to. You can pass a BSTR (or long integer) between a COM client and a COM server without first putting it into a VARIANT. I think a lot of COM programmers, to keep things simple and consistent, probably just use VARIANTs for everything. Scott :)
-
Well, actually, I never said that. You are absolutely correct - you CAN represent BSTR and long integer in a VARIANT. BUT...you don't have to. You can pass a BSTR (or long integer) between a COM client and a COM server without first putting it into a VARIANT. I think a lot of COM programmers, to keep things simple and consistent, probably just use VARIANTs for everything. Scott :)
I agree, Scott! One more question, long integer you mean what data type? Could you write the related name in source codes (C++ and IDL) please? regards, George
-
I agree, Scott! One more question, long integer you mean what data type? Could you write the related name in source codes (C++ and IDL) please? regards, George
In C/C++, a long integer is a four-byte integer value. If you study the valid values for the 'vt' member of a VARIANT (type of variant), you'll notice that the values for four-byte integer are 'VT_I4' (signed four-byte integer) and 'VT_UI4' (unsigned four-byte integer). I'm not sure how VB and C# let you set the variant type, but C++ has a '_variant_t' class that wraps VARIANT and has assignment operators that set it for you, or you can simply set it yourself. In C++, a long integer variable is declared as: long lMyVariable = 0 ; In IDL, you use the "long" keyword, as in these examples: [id(65), helpstring("Load an account from the database for a specific EMS/ambulance run.")] HRESULT LoadForRun( [in] long lAmbRunID, [out] long* plAccountID) ; [id(43), helpstring("Get the first condition indicator for an EMS/ambulance run.")] HRESULT GetFirstConditionIndicator( [out, string] BSTR* pbstrConditionIndicator, [out] long* plConditionIndicatorID) ; Notice that the parameters are of type "BSTR" and "long" (the asterisk, of course, means that a given parameter is actually a pointer to a BSTR or a long). Scott :)
-
In C/C++, a long integer is a four-byte integer value. If you study the valid values for the 'vt' member of a VARIANT (type of variant), you'll notice that the values for four-byte integer are 'VT_I4' (signed four-byte integer) and 'VT_UI4' (unsigned four-byte integer). I'm not sure how VB and C# let you set the variant type, but C++ has a '_variant_t' class that wraps VARIANT and has assignment operators that set it for you, or you can simply set it yourself. In C++, a long integer variable is declared as: long lMyVariable = 0 ; In IDL, you use the "long" keyword, as in these examples: [id(65), helpstring("Load an account from the database for a specific EMS/ambulance run.")] HRESULT LoadForRun( [in] long lAmbRunID, [out] long* plAccountID) ; [id(43), helpstring("Get the first condition indicator for an EMS/ambulance run.")] HRESULT GetFirstConditionIndicator( [out, string] BSTR* pbstrConditionIndicator, [out] long* plConditionIndicatorID) ; Notice that the parameters are of type "BSTR" and "long" (the asterisk, of course, means that a given parameter is actually a pointer to a BSTR or a long). Scott :)
Thanks Scott, What do you want to express by the below statements? C# and VB does not support 4-byte integer or?? -------------------- In C/C++, a long integer is a four-byte integer value. If you study the valid values for the 'vt' member of a VARIANT (type of variant), you'll notice that the values for four-byte integer are 'VT_I4' (signed four-byte integer) and 'VT_UI4' (unsigned four-byte integer). I'm not sure how VB and C# let you set the variant type, -------------------- regards, George