syslog-ng source
cpp-start.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023 Attila Szakacs
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * As an additional exemption you are allowed to compile & link against the
19  * OpenSSL libraries as published by the OpenSSL project. See the file
20  * COPYING for details.
21  *
22  */
23 
24 /*
25  * C++ compat helper headers: "compat/cpp-start.h" and "compat/cpp-end.h"
26  *
27  * Starting your C++ header with #include "compat/cpp-start.h" and ending it
28  * with #include "compat/cpp-end.h" helps you with two things:
29  * - You will be able to include C headers.
30  * - C files will be able to include your C++ header.
31  *
32  * Limitations:
33  * - Obviously you can only write code in your C++ header which is
34  * syntactically correct in a C code, so you cannot define classes, etc.
35  * Do these in either your .cpp file or in a separate .hpp file, which
36  * does not get included in your C code.
37  * - As we are not preparing each C header to be includable in C++ code,
38  * but we are trying to include them with these helpers on the call site,
39  * we cannot be sure that any additional C header include will work.
40  * This adds a level of uncertainty to developing a plugin in C++.
41  *
42  * If you find a C header that cannot be imported to C++ with these helpers,
43  * please try to fix those headers first. If it is not possible, extend this
44  * file with a workaround so others do not run into that issue again.
45  *
46  * Best practices:
47  * - Minimize the C++ code in your plugin, if you can write and build/link
48  * something as C code, do so, for example boilerplates: parser.{c,h}
49  * and plugin.c. This minimizes the chance of including an incompatible
50  * C header.
51  * - Build/link the C++ code as C++ separately and link to that from your
52  * C lib. In case your C++ library is static, add the following to the
53  * the C lib to force linking against the appropriate C++ standard
54  * library (libc++, libstdc++):
55  * nodist_EXTRA_*_SOURCES = force-cpp-linker-with-default-stdlib.cpp
56  * - In your C++ code it is not possible to derive from a C class in the
57  * usual C way by adding a super field and filling its free_fn, because
58  * we do our own reference counting and freeing logic and we cannot rely
59  * on the casting trick of struct packing. You can create a struct
60  * in the usual C inheritance way and have a pointer to your C++ class
61  * in it and you can store a pointer to this struct in your C++ class as
62  * super, so you can access its fields. You can set the necessary virtual
63  * functions with wrapper functions of your real C++ functions in the
64  * ctor of the C style "class" == struct.
65  *
66  * Header ordering:
67  * - syslog-ng.h needs to come first even in cpp/hpp files. You don't
68  * need cpp-start/end wrapper around syslog-ng.h. This include can
69  * happen indirectly, e.g. if you include any other header that should
70  * take care of syslog-ng.h
71  *
72  * - syslog-ng.h will include glib too, which is also C++ safe. This is
73  * needed as some constructs in glib only work if it is outside of an
74  * extern "C" block.
75  *
76  * - Use the usual header ordering conventions, e.g. include the closest
77  * header first (e.g. the one associated with your module) and then
78  * iterate to furthest. This ensures that each header is actually
79  * standalone and includes all its dependencies.
80  *
81  * - If you use a .hpp file, include .h from it and make sure the .h
82  * includes syslog-ng.h and includes all other .h files by wrapping them
83  * using cpp-start/end.h as needed. This takes care of the first rule.
84  *
85  * - In your .cpp files, include the .hpp file but not the .h file which is
86  * already included.
87  *
88  * You can see an example usage of the C++ plugin support at:
89  * modules/examples/sources/random-choice-generator
90  */
91 
92 #ifdef __cplusplus
93 
94 #define this this_
95 
96 extern "C" {
97 
98 #endif