Обсуждение: Passing parameters to a C function

Поиск
Список
Период
Сортировка

Passing parameters to a C function

От
"Rodrigo Sakai"
Дата:

    Hello,

 

   I have a question about passing parameters to a C function.  Imagine the example by PostgreSQL:

 

PG_FUNCTION_INFO_V1(complex_add);

 

Datum

complex_add(PG_FUNCTION_ARGS)

{

      Complex    *a = (Complex *) PG_GETARG_POINTER(0);

      Complex    *b = (Complex *) PG_GETARG_POINTER(1);

      Complex    *result;

 

      result = (Complex *) palloc(sizeof(Complex));

      result->x = a->x + b->x;

      result->y = a->y + b->y;

      PG_RETURN_POINTER(result);

}

 

 So, in the same .C file I have to write another function that calls this one, for example:

 

void

test_main()

{

    Complex *a;

    Complex *b;

 

    a = complex_in("(4.01, 3.77 )");

    printf("a = %s\n", complex_out(a));

 

    b = complex_in("(1.0,2.0)");

    printf("b = %s\n", complex_out(b));

 

    printf("a +  b = %s\n", complex_out(complex_add(a,b)));

}

 

But using version 1 calling convention it won’t work! So, how can I pass the ‘a’ and ‘b’ variables in complex_add(?, ?)?

 

Thanks in advance!

 

 

 

 

Re: Passing parameters to a C function

От
Martijn van Oosterhout
Дата:
On Wed, May 30, 2007 at 11:26:01AM -0300, Rodrigo Sakai wrote:
>    I have a question about passing parameters to a C function.  Imagine the
> example by PostgreSQL:
>
> PG_FUNCTION_INFO_V1(complex_add);


> But using version 1 calling convention it won't work! So, how can I pass the
> 'a' and 'b' variables in complex_add(?, ?)?

Use the DirectFunctionCalln functions in fmgr.

Have a nice day,
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.

Re: Passing parameters to a C function

От
Tom Lane
Дата:
Martijn van Oosterhout <kleptog@svana.org> writes:
> On Wed, May 30, 2007 at 11:26:01AM -0300, Rodrigo Sakai wrote:
>> But using version 1 calling convention it won't work! So, how can I pass the
>> 'a' and 'b' variables in complex_add(?, ?)?

> Use the DirectFunctionCalln functions in fmgr.

There are boatloads of examples in the existing datatype code, for
instance this function in geo_ops.c, which is just applying
close_sb() followed by dist_pb():

Datum
dist_sb(PG_FUNCTION_ARGS)
{   LSEG        *lseg = PG_GETARG_LSEG_P(0);   BOX         *box = PG_GETARG_BOX_P(1);   Point       *tmp;   Datum
result;
 
   tmp = DatumGetPointP(DirectFunctionCall2(close_sb,                                            LsegPGetDatum(lseg),
                                        BoxPGetDatum(box)));   result = DirectFunctionCall2(dist_pb,
           PointPGetDatum(tmp),                                BoxPGetDatum(box));
 
   PG_RETURN_DATUM(result);
}

All that casting to and from Datum is a bit of a pain, but it's worth it
to have a uniform, portable function API.

I strongly suggest adding some appropriate cast macros for your own
datatype, like the ones being used here, instead of dealing directly
with low-level operations like PG_GETARG_POINTER.
        regards, tom lane