Thread: C++ User-defined functions

C++ User-defined functions

From
George Oakman
Date:
Dear all,
 
I am trying to write a user-defined function in C++. Most examples are give in plain C. I would be very grafeful for a sample program/code-snippet in C++.
 
Thank you very much,
 
George.
 
 


Windows Live Hotmail just got better. Find out more!

Re: C++ User-defined functions

From
Craig Ringer
Date:
George Oakman wrote:

> I am trying to write a user-defined function in C++. Most examples are give in plain C. I would be very grafeful for
asample program/code-snippet in C++. 

It's just like any other C/C++ code mixing. You must make sure that any
C-only headers are included within an `extern "C"' block, and declare
any functions that'll be accessed via dlopen() etc as 'extern "C"' too.
You may only use POD types, arrays of POD types, and structs of POD
types (with no methods) in calls to/from C code.

In other words, all PostgreSQL must see is plain C code, but your
'extern "C"' functions may call C++ methods and work with C++ objects
internally.

There's lots more information about this on the Internet. Just look for
generic resources on calling C from C++ and vice versa.

(I don't *think* there are any issues with libstdc++, though you'd
probably have to make sure that no other program linked into Pg brings
in a different version of libstdc++.)

--
Craig Ringer

Re: C++ User-defined functions

From
Tom Lane
Date:
Craig Ringer <craig@postnewspapers.com.au> writes:
> There's lots more information about this on the Internet. Just look for
> generic resources on calling C from C++ and vice versa.

> (I don't *think* there are any issues with libstdc++, though you'd
> probably have to make sure that no other program linked into Pg brings
> in a different version of libstdc++.)

I believe this is fairly platform-dependent.  On platforms where the
standard libc includes everything you need for C++, you'd likely be okay,
but we've seen problems on (possibly obsolete?) platforms where it
doesn't.  One thing you've got to be really wary of is C++ exceptions,
which tend not to interoperate nicely with PG's longjmp-based error
handling.

My own advice is to think twice about how badly your function needs to
be C++ rather than plain C.

            regards, tom lane

Re: C++ User-defined functions

From
George Oakman
Date:
Thanks Craig,
 
I'm trying to compile a very simple test with Visual Studio (2008), but I get the following errors:
 
c:\program files\postgresql\8.3\include\server\pg_config_os.h(188) : error C2011: 'timezone' : 'struct' type redefinition
c:\program files\postgresql\8.3\include\server\pg_config_os.h(188) : see declaration of 'timezone'
c:\program files\postgresql\8.3\include\server\pg_config_os.h(197) : error C2011: 'itimerval' : 'struct' type redefinition
c:\program files\postgresql\8.3\include\server\pg_config_os.h(197) : see declaration of 'itimerval'
c:\program files\postgresql\8.3\include\server\c.h(97) : fatal error C1083: Cannot open include file: 'libintl.h': No such file or directory

I must be doing something wrong - I don't even have a libintl.h on my drive...
 
This is my .cpp file:
 
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
#define _USE_32BIT_TIME_T

#include "postgres.h"
#include <string.h>
#include "fmgr.h"
/* by value */
PG_FUNCTION_INFO_V1(add_one);
        
Datum
add_one(PG_FUNCTION_ARGS)
{
    int32   arg = PG_GETARG_INT32(0);
    PG_RETURN_INT32(arg + 1);
}
 
If you can help, that would be wonderful.
 
Thanks a lot,
 
George.
 
 
> Date: Tue, 10 Mar 2009 02:35:34 +0900
> From: craig@postnewspapers.com.au
> To: oakmang@hotmail.com
> CC: pgsql-general@postgresql.org
> Subject: Re: [GENERAL] C++ User-defined functions
>
> George Oakman wrote:
>
> > I am trying to write a user-defined function in C++. Most examples are give in plain C. I would be very grafeful for a sample program/code-snippet in C++.
>
> It's just like any other C/C++ code mixing. You must make sure that any
> C-only headers are included within an `extern "C"' block, and declare
> any functions that'll be accessed via dlopen() etc as 'extern "C"' too.
> You may only use POD types, arrays of POD types, and structs of POD
> types (with no methods) in calls to/from C code.
>
> In other words, all PostgreSQL must see is plain C code, but your
> 'extern "C"' functions may call C++ methods and work with C++ objects
> internally.
>
> There's lots more information about this on the Internet. Just look for
> generic resources on calling C from C++ and vice versa.
>
> (I don't *think* there are any issues with libstdc++, though you'd
> probably have to make sure that no other program linked into Pg brings
> in a different version of libstdc++.)
>
> --
> Craig Ringer
>
> --
> Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general


Windows Live Hotmail just got better. Find out more!

Re: C++ User-defined functions

From
Magnus Hagander
Date:
George Oakman wrote:
>  Thanks Craig,
>
> I'm trying to compile a very simple test with Visual Studio (2008), but
> I get the following errors:

The PostgreSQL backend and header files are not compatible with Visual
Studio 2008. At least they're not tested wit hit. You need to try Visual
Studio 2005.


> c:\program files\postgresql\8.3\include\server\pg_config_os.h(188) :
> error C2011: 'timezone' : 'struct' type redefinition
> c:\program files\postgresql\8.3\include\server\pg_config_os.h(188) : see
> declaration of 'timezone'
> c:\program files\postgresql\8.3\include\server\pg_config_os.h(197) :
> error C2011: 'itimerval' : 'struct' type redefinition
> c:\program files\postgresql\8.3\include\server\pg_config_os.h(197) : see
> declaration of 'itimerval'
> c:\program files\postgresql\8.3\include\server\c.h(97) : fatal error
> C1083: Cannot open include file: 'libintl.h': No such file or directory
>
> I must be doing something wrong - I don't even have a libintl.h on my
> drive...

libintlh. is part of gettext, which is a dependency from the binary
version of pg. You can either get the whole sourcetree and reconfigure
it without gettext, or install gettext.


//Magnus


Re: C++ User-defined functions

From
Craig Ringer
Date:
Tom Lane wrote:

> One thing you've got to be really wary of is C++ exceptions,
> which tend not to interoperate nicely with PG's longjmp-based error
> handling.

Hmm, that does sound problematic. You can always build with
-fno-exceptions (gcc; I think other compilers offer related options) and
adopt Pg's error handling scheme instead, though.

In general it's possible to use exceptions in C++ code that's being
called from C so long as you make sure you catch all possible exceptions
at the C/C++ interface point.

> My own advice is to think twice about how badly your function needs to
> be C++ rather than plain C.

Yep... unless you have to call C++ libraries or the like I'd be
reluctant to take all the possible bother on board. That's despite
personally having a strong preference for C++.

--
Craig Ringer

Re: C++ User-defined functions

From
Craig Ringer
Date:
Magnus Hagander wrote:
> George Oakman wrote:
>>  Thanks Craig,
>>
>> I'm trying to compile a very simple test with Visual Studio (2008), but
>> I get the following errors:
>
> The PostgreSQL backend and header files are not compatible with Visual
> Studio 2008. At least they're not tested wit hit. You need to try Visual
> Studio 2005.

You should build your extension with the same version of VC++ as the Pg
server was built with anyway, and at the moment that means 2005 if
you're using a stock binary distribution. Otherwise you may encounter
problems with mismatched C runtime libraries, resulting in exciting
problems with memory management, file handles, and other things. IIRC
Pg's use of palloc() should actually avoid the problems with memory
being allocated in one DLL then free()'d in another, but I'd still be wary.

>> c:\program files\postgresql\8.3\include\server\c.h(97) : fatal error
>> C1083: Cannot open include file: 'libintl.h': No such file or directory
>>
>> I must be doing something wrong - I don't even have a libintl.h on my
>> drive...

For some reason the Pg binary distribution doesn't include the headers
for gettext, despite the public backend headers requiring them. (IMO it
really should).

I actually landed up making a dummy libintl.h since I wasn't actually
linking to or using any of the gettext functions, but it'd be much
better to have the correct headers - as noted below:

> libintlh. is part of gettext, which is a dependency from the binary
> version of pg. You can either get the whole sourcetree and reconfigure
> it without gettext, or install gettext.

--
Craig Ringer

Re: C++ User-defined functions

From
Tom Lane
Date:
Craig Ringer <craig@postnewspapers.com.au> writes:
> Tom Lane wrote:
>> One thing you've got to be really wary of is C++ exceptions,
>> which tend not to interoperate nicely with PG's longjmp-based error
>> handling.

> Hmm, that does sound problematic. You can always build with
> -fno-exceptions (gcc; I think other compilers offer related options) and
> adopt Pg's error handling scheme instead, though.

> In general it's possible to use exceptions in C++ code that's being
> called from C so long as you make sure you catch all possible exceptions
> at the C/C++ interface point.

The other half of the problem is that most user-written functions have
some reason to call functions in the core backend.  If any of those
might throw an error then you have to do the reverse mapping too (catch
the longjmp, throw an exception, catch that back at your exit point...).
Otherwise your exception cleanup doesn't happen, which makes the whole
thing a bit useless.

            regards, tom lane

Re: C++ User-defined functions

From
George Oakman
Date:
Hi,

Thank you Craig and Magnus for your answers.
 
I have tried compiling with Visual Studio 2005 and I'm still getting those errors:
 
c:\program files\postgresql\8.3\include\server\pg_config_os.h(188) : error C2011: 'timezone' : 'struct' type redefinition
        c:\program files\postgresql\8.3\include\server\pg_config_os.h(188) : see declaration of 'timezone'

c:\program files\postgresql\8.3\include\server\pg_config_os.h(197) : error C2011: 'itimerval' : 'struct' type redefinition
        c:\program files\postgresql\8.3\include\server\pg_config_os.h(197) : see declaration of 'itimerval'
 
 
Any advice most welcome.
 
Thanks,
 
George.
 

 
> Date: Tue, 10 Mar 2009 11:42:39 +0900
> From: craig@postnewspapers.com.au
> To: magnus@hagander.net
> CC: oakmang@hotmail.com; pgsql-general@postgresql.org
> Subject: Re: [GENERAL] C++ User-defined functions
>
> Magnus Hagander wrote:
> > George Oakman wrote:
> >> Thanks Craig,
> >>
> >> I'm trying to compile a very simple test with Visual Studio (2008), but
> >> I get the following errors:
> >
> > The PostgreSQL backend and header files are not compatible with Visual
> > Studio 2008. At least they're not tested wit hit. You need to try Visual
> > Studio 2005.
>
> You should build your extension with the same version of VC++ as the Pg
> server was built with anyway, and at the moment that means 2005 if
> you're using a stock binary distribution. Otherwise you may encounter
> problems with mismatched C runtime libraries, resulting in exciting
> problems with memory management, file handles, and other things. IIRC
> Pg's use of palloc() should actually avoid the problems with memory
> being allocated in one DLL then free()'d in another, but I'd still be wary.
>
> >> c:\program files\postgresql\8.3\include\server\c.h(97) : fatal error
> >> C1083: Cannot open include file: 'libintl.h': No such file or directory
> >>
> >> I must be doing something wrong - I don't even have a libintl.h on my
> >> drive...
>
> For some reason the Pg binary distribution doesn't include the headers
> for gettext, despite the public backend headers requiring them. (IMO it
> really should).
>
> I actually landed up making a dummy libintl.h since I wasn't actually
> linking to or using any of the gettext functions, but it'd be much
> better to have the correct headers - as noted below:
>
> > libintlh. is part of gettext, which is a dependency from the binary
> > version of pg. You can either get the whole sourcetree and reconfigure
> > it without gettext, or install gettext.
>
> --
> Craig Ringer
>
> --
> Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general


Beyond Hotmail — see what else you can do with Windows Live. Find out more!

Re: C++ User-defined functions

From
3dmashup
Date:
This information is correct  the header file  libintl.h is NOT  included in
the binary distro.
For a workaround, you can  create an empty libintl.h file in local header
directory and add that dir to the include path.
--
View this message in context: http://postgresql.1045698.n5.nabble.com/C-User-defined-functions-tp1911904p2472021.html
Sent from the PostgreSQL - general mailing list archive at Nabble.com.

Re: C++ User-defined functions

From
3dmashup
Date:
This information is correct  the header file  libintl.h is NOT  included in
the binary distro.
For a workaround, you can  create an empty libintl.h file in local header
directory and add that dir to the include path.

When compilinga server side C function with VS2010  or VS2005

The struct  redefiniition is due to  itimerval being defined both  in

include/port/win32.h

and


include/pg_config_os.h

IS this just a matter of getting the order of header includes right?
Or should both files be included?
Or should a struct be defined in both place?

Anyway commenting out the struct  defintion in pg_config_os.h works as a
quick fix hack..

It would be good to know what the right approach is.

Cheers Tim
--
View this message in context: http://postgresql.1045698.n5.nabble.com/C-User-defined-functions-tp1911904p2472055.html
Sent from the PostgreSQL - general mailing list archive at Nabble.com.