receiving pointer through function parameter similar to argv

J

jc

i received a library from a vendor, this will give me a list of names,
when i call the function,

the function definition looks like this

bool ReturnObjects(char **strObjects, int *nCount);
all we have to do is define a pointer like
the implementation on my side will be like

void main(void){
char **strObjects;
int nCount;
ReturnObjects(strObjects, &nCount);
}

i have no idea how they implemented this. i tried to do the same, i
cannot get the values back, unless i define
the function parameters as a triple pointer and call the function as

char **strObjects = NULL;
ReturnObjects(&strObjects, &nCount);

while the function declaration will be like
bool ReturnObjects(char ***strObjects, int *nCount);


what am i doing wrong.

thanks
jc
 
J

Jens Thoms Toerring

jc said:
i received a library from a vendor, this will give me a list of names,
when i call the function,
the function definition looks like this
bool ReturnObjects(char **strObjects, int *nCount);
all we have to do is define a pointer like
the implementation on my side will be like
void main(void){

int main( void ) ;-)
char **strObjects;
int nCount;
ReturnObjects(strObjects, &nCount);
}
i have no idea how they implemented this. i tried to do the same, i
cannot get the values back, unless i define
the function parameters as a triple pointer and call the function as
char **strObjects = NULL;
ReturnObjects(&strObjects, &nCount);
while the function declaration will be like
bool ReturnObjects(char ***strObjects, int *nCount);
what am i doing wrong.

Nothing at all. If the function in the libary is supposed to
return an array of pointers via a function argument then you
definitely need a triple pointer, i.e. a pointer to the array
of pointers to be returned.

Now there are two possibilities: either the documentation
for the function is simly wrong (did you look at the header
file that came with the library and checked that this
function is really declared the way as the documentation
saysit is?). Or there's something in the documentation
that you didn't tell about. It would be possible that the
function has to be passed an existing array of char pointers,
like in

#define MAX_STRINGS

int main( void )
{
char *strObjects[ MAX_STRINGS ];
int nCount = MAX_STRINGS;
ReturnObjects(strObjects, &nCount);

and afterwards up to MAX_STRINGS elements of the strObject
array are initialized (with nCount being set to a lower
value if not that many elements got set).

It might also be interesting to check if it's mentioned
how the memory is to be deallocated if not used anymore
since it might give a hint what's going on below the hood.
But in the end the only people that can really tell are
those that wrote the library...

Regards, Jens
 
B

Ben Pfaff

Eric Sosman said:
Impossible to say for sure, since we don't know what the
"contract" for ReturnObjects is like. My guess (but it's only
a guess) is that you want

char *strObjects;
int nCount;
if (ReturnObjects(&strObjects, &nCount)) ...

That is what I thought at first, too, but I don't see how this
could be used to return a list of names, unless the list is in
the form of, say, a string of comma-separated values.
 
L

lawrence.jones

Eric Sosman said:
This cannot be right.

It's just barely possible that ReturnObjects is actually a macro, which
*could* be made to work. But it's highly unlikely, especially since it
apparently requires the & for the second argument.
 
J

jameskuyper

Ben said:
That is what I thought at first, too, but I don't see how this
could be used to return a list of names, unless the list is in
the form of, say, a string of comma-separated values.

It could be a consecutive series on null-terminated strings all stored
in the same array. I've used interfaces like that, though I didn't
like it. An array of pointers to strings terminated with a null
pointer (such as argv) seems safer to me.
 
J

jayachandran kamaraj

It might also be interesting to check if it's mentioned
how the memory is to be deallocated if not used anymore
since it might give a hint what's going on below the hood.
But in the end the only people that can really tell are
those that wrote the library...
I was told that the double pointer is used, so that the client(i.e.,
my team) doesn't have to worry about memory management. the library
will allocate the memory, populate the array and pass you the pointer,
you process it like make a copy of it(but don't delete it).

my interest here is i'm writing an application, and the team wants me
to develop something similar to the one i referred, so that they don't
have to worry about memory management.

this is an example program that the vendor provided
and this is similar to the one that you offered

bool EXPORT CALL_CONV GetErrorText ( HANDLE hdl,
unsigned short errCode,
char ** errMsg
)

void error(){
char *errortext[256];

GetErrorText (gHdl, GetLastError (gHdl), &errortext[0]);
if (gHdl) OUTPUT("Error occured: " << *errortext);
exit(0);
}

this is a challenge for me. because if i just want one string, i do
this

void GetErrorString(char **str){
*str = my_error_string;//where my_error_string is a string
properly initialized and containts the textt
}
void main(void){
char *str = NULL;
GetErrorString(&str);
}
whether the original pointer was intialized or not was not a concern
at all and i was surprised at the result, i.e., i learned something
new with this process.

jc
 
J

jayachandran kamaraj

I have a get_line function
which does something completely different,
but it has same type parameters
and it is a function which handles its own memory management.

int get_line(char **lineptr, size_t *n, FILE *stream);

It's at:

http://www.mindspring.com/~pfilandr...indspring.com/~pfilandr/C/get_line/get_line.c

Pete
thanks. this is similar to jameskuyper wrote. after i talked to my
team member who actually used that library,
the implementation is the same.
the entire array of names are filled in one very very long character
array and each names are null terminated in the array.
since i saw the double pointer in the function declaration i assumed
that i'll will be getting a array of strings.

so if i need to return an array of string i can only do that by
passing triple pointer.

thanks
jc
 
K

Keith Thompson

jayachandran kamaraj said:
since i saw the double pointer in the function declaration i assumed
that i'll will be getting a array of strings.
[...]

Just a minor point: the term "double pointer" is ambiguous. I suggest
referring to it as a "pointer-to-pointer" unless you actually mean
double*.
 
J

jayachandran kamaraj

jc said:
i received a library from a vendor, this will give me a list of names,
when i call the function,
the function definition looks like this
bool ReturnObjects(char **strObjects, int *nCount);
all we have to do is define a pointer like
the implementation on my side will be like
void main(void){
   char **strObjects;
   int nCount;
   ReturnObjects(strObjects, &nCount);
}
i have no idea how they implemented this. i tried to do the same, i
cannot get the values back, unless i define
the function parameters as a triple pointer and call the function as
char **strObjects = NULL;
ReturnObjects(&strObjects, &nCount);
while the function declaration will be like
bool ReturnObjects(char ***strObjects, int *nCount);
what am i doing wrong.
thanks
jc

You seem close. Have a look at this.

#include <stdio.h>

char *Objects[] = {  "Frank",
                      "Jim",
                      "Mary",
                      "Murphy",
                      NULL
                   };
void ReturnObjects(char ***vect, int *cnt) {
    *vect = Objects;
    *cnt = sizeof Objects / sizeof Objects[0] - 1;

}

int main(void) {
    char **strObjects;
    int nCount, i;
    ReturnObjects(&strObjects, &nCount);
    for (i = 0; i < nCount; ++i)
       printf("%s\n", strObjects);
    return 0;

}


Joe,
exactly that is how i implemented it. i.e., the function declaration
will have a triple pointer.
even though first i didn't believe that it might work,
because my thought process was like this
i'm passing the address of a pointer(which is NULL, because visual
studio was giving me warning that i'm trying to use an uninitialized
variable)
inside the function that pointers address had a value. it got me
really confused

void main(void){
char **strObjects = NULL;//so that i won't have those pesky warnings
int nCount;
//at this point address of the pointer strObjects is 0x0000000
ReturnObjects(&strObjects, &nCount);
}

void ReturnObjects(char ***strObjects, int *nCount){
//here the address of the strObjects is not zero and it was something
valid, when i check the content of that address it was 0x00000
}


the above stuff completely freaked me out.
but it is very cool

thanks
jc

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,059
Members
48,769
Latest member
Clifft

Latest Threads

Top