Question

There is a function with a header such as this:

BPS_API int dialog_event_get_filebrowse_filepaths(bps_event_t* event,
                                            char** file_paths[], int* num_paths);

This is from BlackBerry 10's Native SDK for anyone wondering (it can be found here).

The question is: what am I supposed to provide as the second argument. This function should populate an array of char pointers in order to return the file paths selected.

I tried to call it this way:

char* ar[2];
dialog_event_get_filebrowse_filepaths(event, &ar, &number_paths);

And I am getting an error from QNX Momentics as such:

cannot convert 'char * (*)[2]' to char * * * for argument 2 to int
dialog_event_get_filebrowse_filepaths(bps_event_t *, char * * *, int *)

This seems the most logical way to call it. It needs the memory address of an array of pointer in order to set them, as far as I understand. However, if I declare:

char** ar[2];
dialog_event_get_filebrowse_filepaths(event, ar, &number_paths);

It works, but this way I created an array of pointers to char pointers (an array of arrays of char*). Is this what I should really provide to the function?

Was it helpful?

Solution

The documentation really should have been more explicit, but I'm pretty sure this is what the function expects:

First, a few rules of thumb to help decode the function:

  • the type is really equivalent to a char***. This means we have to find a meaning for three pointers.
  • a string in C is a char* (leaving out the const for brevity). As we expect the function to populate an array of strings, that's one * accounted for.
  • an array in C is generally represented by a pointer. So that's the second *.
  • "output parameters" can be handled in one of two ways: either the caller allocates memory, and passes a pointer, telling callee where to write its data, or the caller does not allocate any memory, and simply passes in a pointer to a pointer. The callee will then modify the "innermost" pointer to point to a chunk of memory allocated by the callee itself. The second approach would account for the last *. This also explains the documentation note that The memory holding these values must be freed using bps_free() when no longer needed -- because the memory was allocated by the library function, rather than by you, it is important that you use the correct free function.

So, the function should be called like this:

char** strs;
dialog_event_get_filebrowse_filepaths(foo, &strs, bar);

When the function returns, strs will point to the first entry of an array of strings allocated by dialog_event_get_filebrowse_filepaths.

OTHER TIPS

Just a guess, but I suspect it should be called like this:

char** ar = 0;
dialog_event_get_filebrowse_filepaths(event, &ar, &number_paths);

The fact that it is declared with array syntax is confusing, but this would be a common way for a C-style function to return an allocated array of strings.

the function will return a string-array and the length via arguments, you can use it like:

char **ar=0;
int i,number_paths = 0;
dialog_event_get_filebrowse_filepaths(event, &ar, &number_paths);
for( i=0; i<number_paths; i++ )
  puts( ar[i] );

and you can/must free the memory ( see lib-docu ) like:

for( i=0; i<number_paths; i++ )
  free( ar[i] );
free( ar );

Here is some (non-Blackberry) code that should satisfy the compiler:

char *file_paths[];
iret = dialog_event_get_filebrowse_filepaths (event, &ar, &number_paths);

The point is

1) do not assign a fixed length in the declaration.

2) pass addressof (&) array pointer to your function

3) make sure somebody (either the API function, or you) allocates the array, and all the strings in the array

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top