Thread: C++ User-defined functions
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!
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!
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
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
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!
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!
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
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
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
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
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!
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!
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.
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.