[geos-devel] Status (New Example)
David Blasby
dblasby at refractions.net
Sat Apr 5 18:29:26 EST 2003
I'm trying to get a C program to talk to GEOS. I'm having difficulties.
I've attached 2 files - a .cpp wrapper for geos and a little .c program.
Basically it passes a string to the
wrapper (test.cpp) that turns it into a Geometry. The resulting
Geometry is wrapper in a GeometryWrapper
and returned to the C program. The C program then passes the
GeometryWrapper to the .cpp library
and asks it to return a string (char *) representation. Really simple,
but it doesnt work.
Here's what happens when I compile and run it. Somehow the Geometry
object gets corrupted.
The programs are very simple, so I must be doing something subtly wrong.
The only real instructions
I've seen for calling C++ from C are at
http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html. I think
I've followed it pretty closely. It does make this warning, though:
>Passing pointers to C++ objects to/from C functions will fail if you
pass and get back something that isn't
>exactly the same pointer. For example, don't pass a base class pointer
and receive back a derived class
>pointer, since your C compiler won't understand the pointer
conversions necessary to handle multiple
>and/or virtual inheritance.
[dblasby at hydra work_dave]$ g++ -g test.cpp -c -I/usr/local/include/geos
; gcc -g test.c -o test test.o -lm -lstdc++ -lgeos ; ./test
geom text (to be parsed):POLYGON((100 200,100 140,180 140,180 200,100 200))
geom (WKTWriter):POLYGON ((100.0000000000000000 200.0000000000000000,
100.0000000000000000 140.0000000000000000, 180.0000000000000000
140.0000000000000000, 180.0000000000000000 200.0000000000000000,
100.0000000000000000 200.0000000000000000))
GEOSasText is about to return : POLYGON ((100.0000000000000000
200.0000000000000000, inf inf, inf inf, inf inf, inf inf))
result in C is POLYGON ((100.0000000000000000 200.0000000000000000, inf
inf, inf inf, inf inf, inf inf))
I'm passing around a GeometryWraper to try to isolate some problems.
Pretty much the same thing happens if you dont use the GeometryWrapper
and just return a Geometry.
Any ideas?
dave
-------------- next part --------------
// g++ -g test.cpp -c -I/usr/local/include/geos
#include <stdio.h>
#include <string>
#include <iostream>
#include <fstream>
//#include "geom.h"
//#include "util.h"
//#include "graph.h"
#include "io.h"
//#include "opRelate.h"
//sometimes the Virtual methods of Geometry can cause problems
// when transiting from C to C++ - this helps to abstract those
// problems. C.F. http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
//
// The same results happen if you dont wrap the Geometry in a simple structure.
typedef struct {
Geometry *g;
} GeometryWrapper;
extern "C" GeometryWrapper *createGEOSFromText(char *wkt);
extern "C" char * GEOSasText(GeometryWrapper *g1);
char *GEOSasText(GeometryWrapper *g)
{
Geometry *g1 = g->g;
WKTWriter *w=new WKTWriter();
string s = w->write(g1);
char *result = (char *) s.c_str();
printf("GEOSasText is about to return : %s\n",result);
return result ;
}
GeometryWrapper *createGEOSFromText(char *wkt)
{
GeometryWrapper *result = (GeometryWrapper *) malloc(sizeof(GeometryWrapper));
//string s= string(wkt);
//string s= "POLYGON((100 200,100 140,180 140,180 200,100 200))";
string s= wkt;
cout <<"geom text (to be parsed):"<<s<<endl;
Geometry *g;
WKTReader *r = new WKTReader(new GeometryFactory(new PrecisionModel(),-1));
g =r->read(s);
WKTWriter *w=new WKTWriter();
string s2 = w->write(g);
cout <<"geom (WKTWriter):"<<s2<<endl;
delete r;
result->g = g;
return result;
}
-------------- next part --------------
//gcc -g test.c -o test test.o -lm -lstdc++ -lgeos
#include "stdio.h"
typedef struct GeometryWrapper GeometryWrapper;
extern GeometryWrapper *createGEOSFromText(char *wkt);
extern char * GEOSasText(GeometryWrapper *g1);
int main(int argC, char* argV[])
{
GeometryWrapper *g = createGEOSFromText("POLYGON((100 200,100 140,180 140,180 200,100 200))");
printf("result in C is %s\n",GEOSasText(g));
}
More information about the geos-devel
mailing list