Board index » cppbuilder » Re: IDL confusion: [out] vs [out, retval] vs [in, out]

Re: IDL confusion: [out] vs [out, retval] vs [in, out]


2004-02-12 09:29:27 AM
cppbuilder102
Hi Remy,
"Remy Lebeau (TeamB)" wrote
[...]
Quote
>When do I use [out, retval]?

When the control has any kind of result value to return to the client.
All
of the control's interface methods should return HRESULT from the coding
aspect of the control interface itself, and then use [out, retval] as the
value that the client will actually see and use. This is essentially a
double-return system, were the HRESULT returns whether the actual method
call succeeded or failed to begin with, and then the [out, retval]
parameter
returns the result value that the client will use from the requested
operation.
OK... I see below you say that VB and scripting languages can directly
assign the return value of the function (which has an [out, retval]
parameter) to a variable and (I assume) that the COM subsystem takes care of
moving the reference parameter around to be used as a return value instead
of the HRESULT in the context of the client call.
This makes me ask the question: In that case, how does the VB client even
inspect the HRESULT since the return value of the function is in fact the
[retval] reference parameter? Can they? Further, does this make the
symantics of calling the function different from, say, Visual C++? (IE:
Does the C++ client context get an HRESULT or the reference parameter like
VB as the return value from the call?)
Above all, it will be important for me that the interface is consistent in
its symantic use and can be called in (as much as possible) exactly the same
way in all environements and languages. This way, my documentation for the
COM server will be easier to understand and more consistent for my clients.
Quote
In other words, a method like this:
HRESULT __stdcall MyControl.SomeMethod(long *ret /*[out, retval]*/);
Would be called like this in VB/scripting:
ret = obj.SomeMethod();
[...]
Quote
>For functions which take BSTR reference parameters which I
>don't care about the initial value and I will be allocating memory
>for, should they be [out], or [out, retval]?
That depends on what the method is actually doing. Is the string value
going to be the actual return value, or will it be used as a secondary
output value when something else is used as the actual return value?
The answer to this question depends on the answer to my questions
above.....Since I want clients to be able to inspect this HRESULT for
success or failure codes in a simple and coinsistent way (across client
languages/IDEs).
Thanx Remy,
You are great.
M.
 
 

Re:Re: IDL confusion: [out] vs [out, retval] vs [in, out]

Hi all,
I want to make sure that my COM servers interface is coded correctly -
according to the standards *my valuable clients will be expecting*.
When do I use [out]?
When do I use [out, retval]?
When do I use [in, out]?
EG: For functions which take BSTR reference parameters which I don't care
about the initial value and I will be allocating memory for, should they be
[out], or [out, retval]? Why? I noticed that the tlb editor automatically
marks property "getters" as [out, retval]...
Lastly - where might I find more information on exactly how to *correctly*
define the IDL parameter spec? (I would prefer a concise, understandable
source of information vs. the full-blown IDL spec from Microsoft, but I
suppose that is the definitive source...)
Great Thanks.
M.
 

Re:Re: IDL confusion: [out] vs [out, retval] vs [in, out]

"Marcus P." < XXXX@XXXXX.COM >wrote in message
Quote
When do I use [out]?
When the control will be using the parameter to only return a value to the
client.
Quote
When do I use [out, retval]?
When the control has any kind of result value to return to the client. All
of the control's interface methods should return HRESULT from the coding
aspect of the control interface itself, and then use [out, retval] as the
value that the client will actually see and use. This is essentially a
double-return system, were the HRESULT returns whether the actual method
call succeeded or failed to begin with, and then the [out, retval] parameter
returns the result value that the client will use from the requested
operation. VB and scripting languages use the HRESULT for extended error
reporting.
In other words, a method like this:
HRESULT __stdcall MyControl.SomeMethod(long *ret /*[out, retval]*/);
Would be called like this in VB/scripting:
ret = obj.SomeMethod();
Quote
When do I use [in, out]?
When the control will be accepting a value from the client and then
returning a value back to the client from the same parameter, possibly a
different value than the original. This is COM's equivilent of passing
parameters by reference in C++.
Quote
For functions which take BSTR reference parameters which I
don't care about the initial value and I will be allocating memory
for, should they be [out], or [out, retval]?
That depends on what the method is actually doing. Is the string value
going to be the actual return value, or will it be used as a secondary
output value when something else is used as the actual return value? Please
show an actual example.
Gambit
 

{smallsort}

Re:Re: IDL confusion: [out] vs [out, retval] vs [in, out]

"Marcus P." < XXXX@XXXXX.COM >wrote in message
Quote
OK... I see below you say that VB and scripting languages can
directly assign the return value of the function (which has an
[out, retval] parameter) to a variable and (I assume) that the
COM subsystem takes care of moving the reference parameter
around to be used as a return value instead of the HRESULT in
the context of the client call.
No, actually that is an internal implementation feature of the VB/scripting
language itself. The COM system is not doing that. What is actually
happening is that the following statement:
ret = obj.SomeMethod
Is parsed and executed as the following by the backend language engine:
if obj.SomeMethod(address of ret) < 0 then a COM error occured
So, either way, the COM object itself is always being accessed the same way.
It is just that the VB/scripting language has a nicer coding syntax that
hides more of the details from the programmer.
Quote
In that case, how does the VB client even inspect the
HRESULT since the return value of the function is in fact
the [retval] reference parameter?
It doesn't. At least not directly. In the case of VB, it has a global Err
object that is filled in with the error information behind the scenes, ie:
Err.Clear
Err.Number = obj.SomeMethod(address of ret)
if Err.Number < 0 then
Err.Description = description obtained from obj
Err.Source = the calling code's line number
' etc...
end if
Then the VB code can do the following:
On Error Resume Next
ret = obj.SomeMethod()
if Err.Number < 0 then
' an error occured
MsgBox Err.Description
else
' all is ok, continue
end if
If you don't use the "On Error" statement, then if the language backend
detects a failed HRESULT from the COM method, it will throw an exception
instead which the VB code will have to catch and handle manually.
Quote
Further, does this make the symantics of calling the function
different from, say, Visual C++? (IE: Does the C++ client context
get an HRESULT or the reference parameter like VB as the return
value from the call?)
C++, whether Microsoft's or Borland's, accesses COM interfaces directly.
Thus calling their methods is the same as calling any other class method in
general, ie:
long result;
HRESULT hres = obj->SomeMethod(&result);
In the case of Borland's wrapper classes, they wrap the [out, retval]
parameters into something that resenbles VB's syntax when accessing the
object:
class MyControlWrapper : public MyControl
{
//...
public:
HRESULT __stdcall SomeMethod(long &result);
long __fastcall SomeMethod();
//...
};
long __fastcall MyControlWrapper::SomeMethod();
{
long result;
OLECHECK(this->SomeMethod(&result));
return result;
}
MyControlWrapper obj = ...;
long result = obj.SomeMethod();
Quote
Above all, it will be important for me that the interface is consistent
in its symantic use and can be called in (as much as possible) exactly
the same way in all environements and languages.
That is what COM is all about, since COM is environment-neutral to begin
with. You don't need to concern yourself with the details about how the
clients are accessing your Control. COM dictates specific rules that every
COM-enabled environment must follow when accessing the COM system itself,
regardless of how the higher level languages of those environments are
interpreting COM operations from the programmer's point of view. As far as
your actual Control is concerned, it is always being accessed the same way
regardless of the environment used.
Quote
This way, my documentation for the COM server will be
easier to understand and more consistent for my clients.
Documentation is a completely different matter than the programming of the
Control itself. All you need to concern yourself with is letting people
know which interfaces are available and what their parameters are. As far
as showing specific code syntaxes, usually that is expressed in terms of C++
declarations, or else several languages for each declaration are shown side
by side. Anyone who is familiar with working with COM under their chosen
environment should be able to understand what you are trying to document in
general and interpret it in terms of their specific environment.
Quote
The answer to this question depends on the answer to my
questions above.....
Then I cannot give you an answer to that question until you ask a question
regarding a specific design choice. Again, the choice between [out] and
[out, retval] depends on the specific needs of the specific method being
written. For example:
HRESULT __stdcall MyControl.get_Name(BSTR *result /*[out, retval]*/);
var name = obj.Name
HRESULT __stdcall MyControl.GetInfo(long* number /*[out]*/, BSTR *name
/*[out]*/, long* result /*[out, retval]*/);
var id, name
var type = obj.GetInfo(id, name)
Gambit