[postgis-users] C question, PG_RETURN_POINTER

Nicolas Ribot nicolas.ribot at scot.cnes.fr
Wed Apr 24 09:51:11 PDT 2002


Hi all,

I have a question concerning C code defining a new function for postgis:

I'm trying to test gpc in association with postgis.
I wrote a C function taking 2 geometries in input, returning a geometry.

It converts the input geometries (POLYGON3D) into gpc objects (works
fine: I can display the right coordinates)
then run a gpc clipping operation (union) on the 2 geometries,
And finally, converts the result into a POLYGON3D.

When displaying the result's coordinates, all is ok, it appears to be a
valid POLYGON3D, all its fields are correct.

Then, I call the make_oneobj_geometry function to convert the POLYGON3D
into a GEOMTRY, and call PG_RETURN_POINTER with the converted object.
After the call, I tested the type, SRID, nobjs attributes of the
GEOMETRY, they are all correct.

PostgreSQL crashes when I call my SQL function relying on the C function
with the following error message:

psql:/tmp/scot_gpc.sql:8: pqReadData() -- backend closed the channel
unexpectedly.
        This probably means the backend terminated abnormally
        before or while processing the request.
psql:/tmp/scot_gpc.sql:8: connection to server was lost

When I call PG_RETURN_NULL instead, it works: a null result is returned
(:->).
Am I doing something wrong with make_oneobj_geometry, or is it
PG_RETURN_POINTER  ?

My config: Postgres 7.1.3 running on windows2000, cygwin.
Postgis 0.6.2.
gpc 2.31 sources.
To compile and link my source code, I have modified the postgis makefile
to include my own files, as I was unable to produce a valid dll (I'm on
Windows), so my function is in postgis.dll.

Thanx for any advice.

Nicolas Ribot.

Following the source code of my function,

PG_FUNCTION_INFO_V1(test_geogpc);
Datum test_geogpc(PG_FUNCTION_ARGS) {
 GEOMETRY      *geom1 =  (GEOMETRY *)
PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
 GEOMETRY      *geom2 =  (GEOMETRY *)
PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
 GEOMETRY      *result = (GEOMETRY *) palloc(sizeof(GEOMETRY) );
 POLYGON3D           *poly1;
 POLYGON3D           *poly2;
 POLYGON3D           *poly_res;
 int32        *offset1;
 int32               *offset2;
 int     poly_res_size;
 char                *o1;
 char                *o2;
 /* gpc types */
 gpc_polygon gpcsubject, gpcclip, gpcresult;

elog(NOTICE,"Entering test_geogpc. Int: %d", toto);
 // looks at the input geometries type
 if (geom1->type != POLYGONTYPE || geom2->type != POLYGONTYPE) {
  elog(ERROR,"Incompatible types for 2 geometries (expected POLYGON)");
  PG_RETURN_NULL();
 }

 if (geom1->SRID != geom2->SRID) {
  elog(ERROR,"Operation on two GEOMETRIES with different SRIDs");
  PG_RETURN_NULL();
 }
 // creates the 2 polygons and 2 gpc polygons on which operations will
be done
 offset1 = (int32 *) ( ((char *) &(geom1->objType[0] ))+ sizeof(int32) *
geom1->nobjs );
 offset2 = (int32 *) ( ((char *) &(geom2->objType[0] ))+ sizeof(int32) *
geom2->nobjs );

 o1 = (char *) geom1 +offset1[0];
 o2 = (char *) geom2 +offset2[0];

 poly1 = (POLYGON3D *)o1;
 poly2 = (POLYGON3D *)o2;

 // creates gpc polygon from postgis polygons:
 scot_gpc_read_polygon(poly1, &gpcsubject);
 scot_gpc_read_polygon(poly2, &gpcclip);

 // perform the clipping operation (union geom1-geom2 for test)
 gpc_polygon_clip(GPC_UNION, &gpcsubject, &gpcclip, &gpcresult);

 //Convert result to opengis polygon:
 poly_res = scot_gpc_write_polygon(&gpcresult, &poly_res_size);

 result = make_oneobj_geometry(poly_res_size,
                               (char *)poly_res,
                               POLYGONTYPE,
                               FALSE,
                               geom1->SRID,
                               geom1->scale,
                               geom1->offsetX,
                               geom1->offsetY
                               );
 // free memory for gpc polygons.
 gpc_free_polygon(&gpcsubject);
 gpc_free_polygon(&gpcclip);
 gpc_free_polygon(&gpcresult);

 PG_RETURN_POINTER(result);
}

The SQL function definition

CREATE FUNCTION test_geogpc(GEOMETRY,GEOMETRY)
RETURNS GEOMETRY
AS
'C:/cygwin/usr/src/postgresql-7.1.3-2/contrib/postgis-0.6.2/postgis.dll'

LANGUAGE 'c'  with (isstrict);

and I call:
  select test_geogpc
  (
  (select geom from testgpc where id=1),
  (select geom from testgpc where id=2)
  )
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20020424/ab822756/attachment.html>


More information about the postgis-users mailing list