3

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?

  • 1
    @Macmade It may be a beginner's mistake, but your irony doesn't seem to help me much. Care to explain more in detail? –  May 27 '12 at 20:26
  • 1
    The function wants `char** file_paths[]` an array of pointers ot pointers to `char` (probably, an array of pointers to `char`-arrays is the intended usage), so give that to it, as your second example. Maybe you ought to allocate storage for the array-members before calling. – Daniel Fischer May 27 '12 at 20:28
  • @Daniel Fischer I doubt I need to allocate anything since the documentation says that the things returned should be cleared with bps_free(), an SDK function. Macmade is probably right - I probably needed to cast to (char***) in the first example. It works that way. –  May 27 '12 at 20:31
  • Actually, I believe the function wants a pointer to char* file_paths[]. Slight difference ;) – paulsm4 May 27 '12 at 20:32
  • 2
    @Alex One would need to consult the documentation. The way it's written suggests it wants an array of pointers to C strings. But as a function argument, that's a `char ***`, so Vaughn Ctao's guess might be right. Casting a 'pointer to array of `char*`' to that type might be the right thing, but doesn't correspond well to the signature. – Daniel Fischer May 27 '12 at 20:39
  • @Daniel Fischer Yes, you are probably right on that Vaughn Ctao is right (talking about indirection, heh). As I said in a comment, I will test that, and if it returns correct results, I will mark it as an answer. However, they have chosen a very inconvenient way of declaring parameters knowing all the confusion with pointers and arrays of chars. –  May 27 '12 at 20:46
  • I'm not saying anybody's right (or wrong). I haven't sufficient information about the function for that. – Daniel Fischer May 27 '12 at 20:49
  • Nor do I, that's the problem, the documentation says only as much. –  May 27 '12 at 20:49
  • @Alex: what **does** the documentation say? – jalf May 27 '12 at 22:05

4 Answers4

3

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.

jalf
  • 243,077
  • 51
  • 345
  • 550
2

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.

Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
  • This would certainly compile, I tried it already, but I haven't tested it yet. If it works after I test, I will mark this as the answer to the question. –  May 27 '12 at 20:37
2

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 );
user411313
  • 3,930
  • 19
  • 16
1

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

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • If I don't assign a fixed length, the compiler says: storage size of file_paths isn't known –  May 27 '12 at 20:30
  • `char *file_paths[];` is not valid C-array definition; which C compiler will compile this? – user411313 May 27 '12 at 21:48