2 34.13. C++ Applications #
4 34.13.1. Scope for Host Variables
5 34.13.2. C++ Application Development with External C Module
7 ECPG has some limited support for C++ applications. This section
8 describes some caveats.
10 The ecpg preprocessor takes an input file written in C (or something
11 like C) and embedded SQL commands, converts the embedded SQL commands
12 into C language chunks, and finally generates a .c file. The header
13 file declarations of the library functions used by the C language
14 chunks that ecpg generates are wrapped in extern "C" { ... } blocks
15 when used under C++, so they should work seamlessly in C++.
17 In general, however, the ecpg preprocessor only understands C; it does
18 not handle the special syntax and reserved words of the C++ language.
19 So, some embedded SQL code written in C++ application code that uses
20 complicated features specific to C++ might fail to be preprocessed
21 correctly or might not work as expected.
23 A safe way to use the embedded SQL code in a C++ application is hiding
24 the ECPG calls in a C module, which the C++ application code calls into
25 to access the database, and linking that together with the rest of the
26 C++ code. See Section 34.13.2 about that.
28 34.13.1. Scope for Host Variables #
30 The ecpg preprocessor understands the scope of variables in C. In the C
31 language, this is rather simple because the scopes of variables is
32 based on their code blocks. In C++, however, the class member variables
33 are referenced in a different code block from the declared position, so
34 the ecpg preprocessor will not understand the scope of the class member
37 For example, in the following case, the ecpg preprocessor cannot find
38 any declaration for the variable dbname in the test method, so an error
42 EXEC SQL BEGIN DECLARE SECTION;
44 EXEC SQL END DECLARE SECTION;
54 EXEC SQL CONNECT TO testdb1;
55 EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL CO
61 EXEC SQL SELECT current_database() INTO :dbname;
62 printf("current_database = %s\n", dbname);
67 EXEC SQL DISCONNECT ALL;
70 This code will result in an error like this:
72 test_cpp.pgc:28: ERROR: variable "dbname" is not declared
74 To avoid this scope issue, the test method could be modified to use a
75 local variable as intermediate storage. But this approach is only a
76 poor workaround, because it uglifies the code and reduces performance.
79 EXEC SQL BEGIN DECLARE SECTION;
81 EXEC SQL END DECLARE SECTION;
83 EXEC SQL SELECT current_database() INTO :tmp;
84 strlcpy(dbname, tmp, sizeof(tmp));
86 printf("current_database = %s\n", dbname);
89 34.13.2. C++ Application Development with External C Module #
91 If you understand these technical limitations of the ecpg preprocessor
92 in C++, you might come to the conclusion that linking C objects and C++
93 objects at the link stage to enable C++ applications to use ECPG
94 features could be better than writing some embedded SQL commands in C++
95 code directly. This section describes a way to separate some embedded
96 SQL commands from C++ application code with a simple example. In this
97 example, the application is implemented in C++, while C and ECPG is
98 used to connect to the PostgreSQL server.
100 Three kinds of files have to be created: a C file (*.pgc), a header
101 file, and a C++ file:
104 A sub-routine module to execute SQL commands embedded in C. It
105 is going to be converted into test_mod.c by the preprocessor.
107 #include "test_mod.h"
113 EXEC SQL CONNECT TO testdb1;
114 EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL CO
121 EXEC SQL BEGIN DECLARE SECTION;
123 EXEC SQL END DECLARE SECTION;
125 EXEC SQL SELECT current_database() INTO :dbname;
126 printf("current_database = %s\n", dbname);
132 EXEC SQL DISCONNECT ALL;
136 A header file with declarations of the functions in the C module
137 (test_mod.pgc). It is included by test_cpp.cpp. This file has to
138 have an extern "C" block around the declarations, because it
139 will be linked from the C++ module.
147 void db_disconnect();
154 The main code for the application, including the main routine,
155 and in this example a C++ class.
157 #include "test_mod.h"
186 TestCpp *t = new TestCpp();
192 To build the application, proceed as follows. Convert test_mod.pgc into
193 test_mod.c by running ecpg, and generate test_mod.o by compiling
194 test_mod.c with the C compiler:
195 ecpg -o test_mod.c test_mod.pgc
196 cc -c test_mod.c -o test_mod.o
198 Next, generate test_cpp.o by compiling test_cpp.cpp with the C++
200 c++ -c test_cpp.cpp -o test_cpp.o
202 Finally, link these object files, test_cpp.o and test_mod.o, into one
203 executable, using the C++ compiler driver:
204 c++ test_cpp.o test_mod.o -lecpg -o test_cpp