Dont think code it

2013-3-10 Wrapping C++ exceptions, templated and classes in C

Sometime some libraries is distributed only as C++ libs or in template
code. Or plug-ins for some programs is only in C or other language.

Here can join C and C++ compiled code and there will no big difference
with language you use. Only need to choose right compiler for compilation.
C++ stuff can be easily hidden and you can use some C++ "only" features
in C without notice it.

Use templates from C.

Templates is most C++'sh part of all. Templates are defined in C++ headers
and there not generate code. Only when you use they generate code.
It reason why cannot include them inside *.so or *.a libraries.
But you can always generated templates function examples that will
generate code. And it means it now can be inside *.so and *.a.
To use templates from C and compile it with C we need to hide C++ headers
from C and create templates generated code

C compatible header code.h

	extern float cmpx_add_f(float, float);
	extern int   cmpx_add_i( int, int );

C++ template code.hpp

	template <typename T>
	inline T cmpx_add( T a, T b )
		return a+b;

Tell C++ to generate code for specific templates code.hpp

	template int cmpx_add<int>(int, int);
	template float cmpx_add<float>(float, float);

Write C compatible wrapper in C++

	float cmpx_add_f( float a, float b )
		return cmpx_add<float>(a,b);

	int cmpx_add_i( int a, int b )
		return cmpx_add<int>(a,b);

lets see now object file info
readelf -a

18: 0000000000000000 63 FUNC GLOBAL DEFAULT 5 cmpx_add_f
20: 0000000000000000 42 FUNC WEAK DEFAULT 13 _Z8cmpx_addIfET_S0_S0_
21: 000000000000003f 31 FUNC GLOBAL DEFAULT 5 cmpx_add_i
22: 0000000000000000 20 FUNC WEAK DEFAULT 12 _Z8cmpx_addIiET_S0_S0_

We see that functions inside code.h is globally visible and we can use them
without problem from C.

Use C++ exceptions

Exceptions is usually very C++'sh everyone know that exceptions cannot be
used in C. There is some C libraries that add some kind exceptions for
C. That libraries usually uses setjmp and longjmp for simulating that kind of stuff.

C header

	extern void  raise_exception( int );

C++ code for raising exceptions

extern void raise_exception( int a )
		int b;
		b = b/a;
		printf("Everything ok ;]\n");
	catch ( int e )
		printf("Catching up exception number %d \n",e);

C use exceptions

	raise_exception( 1 );
	raise_exception( 0 );

Here is seen that C++ exception raises inside C code. There can be made
some code additions and C++ exceptions can be used in C with some tricks.
Not yet proof of concept. But with pointers to functions
(wasn't they called callbacks?) it cone be done.

Use C++ classes

C completable headers

	extern void* clA_init();
	extern void  clA_add( void*,int, int );
	extern int   clA_empty( void* );
	extern void  clA_destroy( void* );

C++ class definitions

class A
		char *p;
		void add( int, int );
		bool empty();

C++ class implementation

	this->p = (char *)malloc(1024);

	printf("Free Class Baby!!!\n");
	if (this->p != NULL)
		free( this->p);

void A::add( int a, int b )
	int i = cmpx_add_i( a , b );
	printf("%d\n", i);

bool A::empty()
	if (this->p == NULL)
		return true;
		return false;

C++ wrapping functions

extern void* clA_init()
	A *a = new A;
	return (void *)a;

extern void clA_add( void *c, int a, int b )
	A *cl=(A*)c;
	cl->add( a, b );

extern int clA_empty( void *c )
	A *cl=(A*)c;
	bool b = cl->empty();
	if ( b == true ) 
		return 1;
	} else
		return 0;

extern void clA_destroy( void *c )
	A *cl = (A*)c;

It easy to give C++ class to C as void* and then use
C++ class functions (wasnt they called methods?) from C
simply as pointers. It segfault oriented but it the way how it works.

These examples shows that you can stay as much as possible with C
and use C++ compiled code.