[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