Re: server-side extension in c++ - Mailing list pgsql-general
From | Bruce Momjian |
---|---|
Subject | Re: server-side extension in c++ |
Date | |
Msg-id | 201006020326.o523QXM01845@momjian.us Whole thread Raw |
In response to | Re: server-side extension in c++ (Craig Ringer <craig@postnewspapers.com.au>) |
List | pgsql-general |
Craig Ringer wrote: > ( BTW, all in all, I agree with Tom Lane - the best answer is "don't". > Sometimes you need to access functionality from C++ libraries, but > unless that's your reason I wouldn't ever consider doing it. ) > > Here's a rough outline of the rules I follow when mixing C/C++ code, > plus some info on the longjmp error handling related complexities added > by Pg: This was very helpful. I have condensed your ideas into the attached patch that contains the potential C++ documentation section. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + None of us is going to be here forever. + Index: doc/src/sgml/extend.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/extend.sgml,v retrieving revision 1.42 diff -c -c -r1.42 extend.sgml *** doc/src/sgml/extend.sgml 1 Jun 2010 03:19:36 -0000 1.42 --- doc/src/sgml/extend.sgml 2 Jun 2010 03:25:30 -0000 *************** *** 273,280 **** &xoper; &xindex; - <!-- Use this someday when C++ is easier to use. bjm 2010-05-31 - <sect1 id="extend-Cpp"> <title>Using C++ for Extensibility</title> --- 273,278 ---- *************** *** 284,325 **** <para> It is possible to use a compiler in C++ mode to build ! <productname>PostgreSQL</productname> extensions; you must simply ! follow the standard methods for dynamically linking to C executables: <itemizedlist> <listitem> <para> ! Use <literal>extern C</> linkage for all functions that must ! be accessible by <function>dlopen()</>. This is also necessary ! for any functions that might be passed as pointers between ! the backend and C++ code. </para> </listitem> <listitem> <para> ! Use <function>palloc()</> to allocate any memory that might be ! freed by the backend C code (don't pass <function>new()</>-allocated ! memory). ! </para> </listitem> <listitem> <para> ! Use <function>pfree()</> to free memory allocated by the backend ! C code (do not use <function>delete()</> for such cases). </para> </listitem> <listitem> <para> ! Prevent exceptions from propagating into the C code (use a ! catch-all block at the top level of all <literal>extern C</> ! functions). </para> </listitem> </itemizedlist> </para> </sect1> - --> </chapter> --- 282,338 ---- <para> It is possible to use a compiler in C++ mode to build ! <productname>PostgreSQL</productname> extensions by following these ! guidelines: <itemizedlist> <listitem> <para> ! All functions accessed by the backend must present a C interface ! to the backend; these C functions can then call C++ functions. ! For example, <literal>extern C</> linkage is required for ! backend-accessed functions. This is also necessary for any ! functions that are passed as pointers between the backend and ! C++ code. </para> </listitem> <listitem> <para> ! Free memory using the appropriate deallocation method. For example, ! most backend memory is allocated using <function>palloc()</>, so use ! <function>pfree()</> to free it, i.e. using C++ ! <function>delete()</> in such cases will fail. </listitem> <listitem> <para> ! Prevent exceptions from propagating into the C code (use a ! catch-all block at the top level of all <literal>extern C</> ! functions). This is necessary even if the C++ code does not ! throw any exceptions because events like out-of-memory still ! throw exceptions. Any exceptions must be caught and appropriate ! errors passed back to the C interface. If possible, compile C++ ! with <option>-fno-exceptions</> to eliminate exceptions entirely; ! in such cases, you must check for failures in your C++ code, e.g. ! check for NULL returned by <function>new()</>. </para> </listitem> <listitem> <para> ! If calling backend functions from C++ code, be sure that the ! C++ call stack contains only plain old data structure ! (<acronym>POD</>). This is necessary because backend errors ! generate a <function>longjump()</> that does not properly unroll ! a C++ call stack with non-POD objects. </para> </listitem> </itemizedlist> </para> + <para> + In summary, it is best to place C++ code behind a wall of + <literal>extern C</> functions that interface to the backend, + and avoid exception, memory, and call stack leakage. + </para> </sect1> </chapter>
pgsql-general by date: