I am working on a RedRat code project for my job these days. The RedRat is a device that can be used to control 16 IR outputs, and my plan is to use this for testing of STBs with my own program.

+++++++++++++++++++++++++++
For those interested >>
http://www.redrat.co.uk/software/SDK/index.html
+++++++++++++++++++++++++++

I've been working with code before in C# and Java, but this is the first time I really delve into C++. And apart from a universe of new things to learn (especially windows specific things) I have stumbled across some function arguments that I do not understand.

In the RedRat COM API there are two particular functions:

1. HRESULT FindRedRat4s([out, retval] SAFEARRAY(BSTR)* pRetVal);
2. My questions is: what is the definition of [out] and [retval] specifications, and what do they mean in practice?
1. HRESULT GetRedRat4(

2. [in] BSTR rr4Name,

3. [out, retval] ICCWRedRat4** pRetVal);
4. What does the double ** mean?

Hope you can help with this :-)

** means pointer to a pointer
If it's an 2d-array (**) is *generally* same as (*)

I understand. I was a bit confused. What is the point (eheh) of a pointer to a pointer?

Which leads me to another question: is there any way to tell if the function generates the safearray itself, or if I have to instantiate one myself? From my point of view this must have something to do with the [out, retval] parameter..

Puzzled =S

> What is the point (eheh) of a pointer to a pointer?
The two most common uses are faking a 2D array with heap memory, and faking pass by reference for a pointer. The code you posted looks like the latter. The output of the function is a pointer, but the function cannot modify that pointer unless you pass a pointer to the pointer, or a reference to the pointer. The library chose to implement the double pointer method instead of the reference method, probably for interoperability with C, where there are no references. :)

The [out,retval] looks like an annotation to me, but I have never seen it this way. What compiler do you use?

If it is an annotation it is basically an aid for the compiler, or some code verification tool. For instance if you as programmer are to delete the returned pointer, a verification tool has to know what the returned pointer is... and check if you really are deleting it.

Especially microsoft is doing a lot of (good) work in this, in the field of driver development pretty much anything can be annotated.

but the function cannot modify that pointer unless you pass a pointer to the pointer, or a reference to the pointer

But isn't it limited to when you specify the function argument as: void func(const int *p); ?

> But isn't it limited to when you specify the function argument as: void func(const int *p); ?
Ed doesn't understand the question.

A function cannot modify to what a pointer is pointing to if you specify it as const. But in your above post you are saying pointer's are by default passed as a const pointer, I'm clarifying that.

> A function cannot modify to what a pointer is pointing to if you specify it as const.
Yes. :)

> But in your above post you are saying pointer's are by default passed as a const pointer
Apologies for the confusion. Ed is saying that the only way to reset a pointer from another function is by passing a pointer to that pointer, or by passing a reference to that pointer.

``````void foo(int *p)
{
p = new int(10); // Memory leak, p is a copy
}

void bar(int **p)
{
*p = new int(10); // OK, the original pointer is reset
}

void baz(int*& p)
{
p = new int(10); // OK, the original pointer is reset
}``````

const complicates things, so Edward's post did not mention it.

Thank you for the clarification. But I have a doubt that can't we simply memset() the pointer to 0 to reset it rather fetching a reference for it.

``````void foo(int *p)
{
memset(p,0,sizeof(*p)); //This ought to do it.
}``````

And I didn't exactly get you on "reset". If you meant the same I did above & are emphasizing the fact that there are other ways to do it (a la the OP's Snippet), that just makes my question vague. :)

> But I have a doubt that can't we simply memset() the pointer to 0 to reset it rather fetching a reference for it.
Your code is conceptually the same as the following.

``````void foo1(int *p)
{
p = 0;
}

int main()
{
int *q;
foo1(q);
}``````

Ignoring for now that memset() on a pointer is bad juju, do not forget that pass-by-value is the default even for pointers. In foo1(), p is a *copy* of q. You can change p all you want, but q will never change. You can dereference p and access the object that q points to, but you cannot reset q to point to a different object.

The only way to modify q from p is to make p either a pointer to a pointer

``````void foo1(int **p)
{
*p = 0;
}

int main()
{
int *q;
foo1(&q);
}``````

or a reference

``````void foo1(int*& p)
{
p = 0;
}

int main()
{
int *q;
foo1(q);
}``````

Thanks, gotcha.

The [out,retval] looks like an annotation to me, but I have never seen it this way. What compiler do you use?

If it is an annotation it is basically an aid for the compiler, or some code verification tool. For instance if you as programmer are to delete the returned pointer, a verification tool has to know what the returned pointer is... and check if you really are deleting it.

Especially microsoft is doing a lot of (good) work in this, in the field of driver development pretty much anything can be annotated.

I use the Visual Studio C++ 2010 express IDE - but I am not terribly certain what compiler it is using.

Is there any way to tell if the function generates the safearray itself, or if I have to instantiate one myself?

I'm still a bit confused regarding my above question. I am passing a SAFEARRAY "pointer - to - a - pointer" to the COM API. But how do I know if the API either 1) creates the safearray itself or 2) The pointer I pass to the API has to point to a SAFEARRAY I created myself?

I'm still a bit confused regarding my above question. I am passing a SAFEARRAY "pointer - to - a - pointer" to the COM API. But how do I know if the API either 1) creates the safearray itself or 2) The pointer I pass to the API has to point to a SAFEARRAY I created myself?

This is generally answered by the Documentation for that specific function. But I guess you don't have it you'll have to try the hard way.
If you pass an un-allocated Pointer to the function & it comes out well (read: Doesn't crash) that means the function is allocating memory for it. Else if you get a run-time crash you have to allocate the memory for the pointer & pass it's reference. In any case try to get the documentation for best way out.