views:

88

answers:

2

This is driving me crazy:

I have function

void gst_init(int *argc, char **argv[]);

in the gstreamer api and I want to call it with some parameters I define, like:

int argc = 2;
char* argv[2] = {"myvalue1", "myvalue2"};
gst_init(&argc, &argv);

This code doesn't compile (I get error C2664):

error C2664: 'gst_init' : cannot convert parameter 2 from 'char *(*)[2]' to 'char **[]'

The question: How do I define the argv value to pass it as a parameter? I've been using C++ for over 5 years, but I haven't used a raw array since ... high-school I think (more than five years ago).

Edit: I'm using VS2010 Express.

+2  A: 

Try

int argc = 2;
char* arg1[1] = {"myvalue1"};
char* arg2[1] = {"myvalue2"};
char** argv[2] = { arg1, arg2 };
gst_init(&argc, argv);

char **argv[] is an array of char**, which is analogous to an array of char* arrays.

OTOH what you tried to pass as parameter is shown as char *(*)[2]: a pointer to an array of char*.

Péter Török
doesn't work: `error C2440: 'initializing' : cannot convert from 'const char [9]' to 'char **'`
utnapistim
@utnapistim, see my update.
Péter Török
The updated code compiles OK. I will go over it. Thanks.
utnapistim
-1 don't do that. gst_init takes pointers so it can 'remove' the arguments from the command line which it processes by modifying *argc and *argv.
Pete Kirkham
@Pete, so what should he do instead? I had a similar feeling and the OP tried a similar solution, but it doesn't seem to work.
Péter Török
+3  A: 

Normally you would follow the instructions in the manual, and pass pointers to the arguments provided by main, so that gstreamer can remove the arguments which it handles.

#include <stdio.h>
#include <gst/gst.h>

int main ( int argc, char *argv[] )
{
    gst_init (&argc, &argv);
    // handle the remaining argc values of argv

If you want to create your own arguments, then create the same sort of array which main would have:

void gst_init(int *argc, char **argv[])
{
    // strip one argument
    --*argc;
    ++*argv;
}

void foo ()
{
    int argc = 2;

    char* args[] = {"myvalue1", "myvalue2"};
    char** argv = args;

    for(int i= 0; i < argc; ++i)
        printf("%s\n", argv[i]);

    gst_init(&argc, &argv);

    for(int i= 0; i < argc; ++i)
        printf("%s\n", argv[i]);
}

If you're not using C99, it's easier to have a separate pointer to the local array of string literals. Using C99, you could just write char** argv = (char*[]){"myvalue1", "myvalue2"}; to start with a pointer to the first element in an anonymous array.

You need to pass a pointer to a variable pointing to the array rather than a pointer to the first element in the array; in the first case the degradation of an array parameter to a pointer achieves the same effect as the second case declaring a pointer local variable - you then can pass the address of this variable and the function can modify it. sizeof( args) is 8 on a 32bit machine as the compiler deduces the number of elements in the array; sizeof(argv) is 4, therefore ++args would move the pointer to the end of the array rather than to the next element as ++argv does. The compiler protects you from such an operation.

But normally you'd use it in the way the manual suggests.

Pete Kirkham
I know I should pass the args and argv -- I was just curious on how to manually define the parameters (that is why I didn't tag the question "gstreamer" - I was just interested in the syntax). Thanks for the answer though (I got something else from it).Have a +1 :)
utnapistim