summaryrefslogtreecommitdiff
path: root/ACE/docs/Symbol_Versioning.html
blob: d0d50bca91409c3210d77ccf7746801a6155c3f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<!-- $Id$ -->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Symbol Versioning in ACE</title>
  </head>

  <body>
    <h3>Symbol Versioning in ACE</h3>

    <p>
      To provide a means for ACE-based application developers to avoid
      symbol conflicts when multiple versions of ACE are linked to an
      application ACE supports <em>versioned namespaces</em>.  When
      enabled (disabled by default), ACE's versioned namespace support
      causes all ACE symbols (classes, free functions, etc) to be
      placed within a C++ namespace of the form "<code>namespace
        ACE_5_5_1</code>".  For example, the <code>ACE_Reactor</code>
      would end up being placed in the versioned namespace like so:
    </p>

    <blockquote>
      <code>
<pre>
        namespace ACE_5_5_1
        {
          class ACE_Reactor
          {
            ...
          };
        }
        using namespace ACE_5_5_1;
</pre>
      </code>
    </blockquote>

    <p>
      Notice that a <code>using</code> clause exposes the ACE types
      embedded in the versioned namespace back to the global
      namespace.  This maximizes source code compatibility.  ACE
      itself does this through the use of two macros:
    </p>
    <ul>
      <li>
        <code>ACE_BEGIN_VERSIONED_NAMESPACE_DECL</code><br>
        <ul>
          <li>
            Expands to "<code>namespace ACE_VERSIONED_NAMESPACE NAME
              {</code>", where
            <code>ACE_VERSIONED_NAMESPACE_NAME</code> by defaults to
            namespace name of the form
            <code>ACE_<em>major</em>_<em>minor</em>_<em>beta</em></code>.
            Users may override the default by defining the
            <code>ACE_VERSIONED_NAMESPACE_NAME</code> preprocessor
            symbol in their <code><strong>ace/config.h</strong></code>
            header file.
          </li>
        </ul>
      </li>
      <li>
        <code>ACE_END_VERSIONED_NAMESPACE_DECL</code>
        <ul>
          <li>
            Expands to "<code>} using namespace
              ACE_VERSIONED_NAMESPACE_NAME;</code>", where
            <code>ACE_VERSIONED_NAMESPACE_NAME</code> is described
            above.
          </li>
        </ul>
      </li>
    </ul>
    <h2>Things ACE-based Application Developers Should Know</h2>
    <p>
      Every effort has been made to make the versioned namespace
      support in ACE as transparent as possible, including transparent
      versioned symbol support in the ACE_Service_Configurator when
      the ACE_Service_Configurator macros, such as <em>e.g.</em>,
      <code>ACE_FACTORY_DECLARE</code>, are used appropriately.  No
      changes to service configurator directives are necessary.  For
      example, the <code>ACE_Service_Configurator</code> will
      transparently mangle the factory function name in a service
      configurator directive on-the-fly, meaning it will only load a
      "versioned" factory function name.  This allows multiple service
      object factory functions, for example, to coexist in the same
      process space.
    </p>
    <p>
      There is, however, at least one caveat with respect to source
      code compatibility: any forward declarations of ACE symbols must
      also be placed within the versioned namespace.  For example, if
      you have a forward declaration for <code>ACE_Reactor</code> in
      your application code, you will need to place it within the
      configured ACE versioned namespace as follows:
    </p>
    <blockquote>
      <code>
<pre>
        ACE_BEGIN_VERSIONED_NAMESPACE_DECL
        class ACE_Reactor;
        ACE_END_VERSIONED_NAMESPACE_DECL
</pre>
      </code>
    </blockquote>
    <p>
      This must only be done once, as these macros hide the versioned
      namespace name details from the application.  Alternatively, you
      could place the forward declaration in a namespace that is an
      alias of the ACE versioned namespace, <em>e.g.</em>:
    </p>
    <blockquote>
      <code>
<pre>
        namespace Foo = ACE_VERSIONED_NAMESPACE_NAME;</code>
        namespace Foo {
          class ACE_Reactor;
        }
        using namespace Foo;
</pre>
      </code>
    </blockquote>
    <p>
      Versioned namespace support in ACE may be enabled by adding
      <code>versioned_namespace=1</code> to your MPC
      <code><strong>default.features</strong></code> file.
    </p>

    <h2>Things ACE Developers Should Know</h2>
    <p>
      ACE developers should place all ACE symbols that are potentially
      exposed to the user, including forward declarations in a
      versioned namespace using the
      <code>ACE_BEGIN_VERSIONED_NAMESSPACE_DECL</code> and
      <code>ACE_END_VERSIONED_NAMESPACE_DECL</code> macros.  Free
      functions that are declared to have a C calling convention
      (<em>i.e.</em>, <code>extern "C"</code>) should have their names
      mangled using the <code>ACE_PREPROC_CONCATENATE</code>
      preprocessor.  For example:
    </p>
    <blockquote>
      <code>
<pre>
        void ACE_func (void) { ... }
        ...
        ACE_func(); // Call ACE_func()
</pre>
      </code>
    </blockquote>
    <p>
      becomes:
    </p>
    <blockquote>
      <code>
<pre>
        #if (defined (ACE_HAS_VERSIONED_NAMESPACE) \
             && ACE_HAS_VERSIONED_NAMESPACE == 1) \
          && !(defined (_MSC_VER) && _MSC_VER <= 1200)
        // MSVC++ 6's preprocessor can't handle macro expansions
        // required by the versioned namespace support.  *sigh*

        # define ACE_FOO_FUNC_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_foo_func)

        #else

        # define ACE_FOO_FUNC_NAME ACE_foo_func

        #endif  /* ACE_HAS_VERSIONED_NAMESPACE == 1 */

        ...
        void ACE_FOO_FUNC_NAME (void) { ... }

        ACE_FOO_FUNC_NAME();  // Call mangled ACE_foo_func().
</pre>
      </code>
    </blockquote>
    <p>
      The <code>ACE_PREPROC_CONCATENATE</code> is used rather than a
      straight <code>##</code> preprocessor concatenation since in the
      latter case preprocessor symbols like
      <code>ACE_VERSIONED_NAMESPACE_NAME</code> will not be expanded
      if they are concatenated.  <code>ACE_PREPROCE_CONCATENATE</code>
      forces the preprocessor to expand them during the argument
      prescan by calling a macro that itself calls another that
      performs the actual concatenation.
    </p>
    <h3>General Guidelines</h3>
    <ul>
      <li>
        Versioned namespace macro/support must be added to all new files
        added to ACE.
      </li>
      <li>
        Do not place include directives between
        <code>ACE_BEGIN_VERSIONED_NAMESPACE_DECL</code> and
        <code>ACE_END_VERSIONED_NAMESPACE_DECL</code> macros.  Doing
        so  will cause nested namespace to be created, which is not
        the desired affect.
      </li>
      <li>Be aware of preprocessor conditional blocks when placing the
        versioned namespace macros.  For example, if you open
        versioned namespace within a given preprocessor condition
        block, you'll most likely want to close it in the same
        block.
      </li>
      <li>
        If necessary, reopen and close the versioned namespace
        multiple times in the same file by using the macros multiple
        times to address the concerns described in the above two
        items.
      </li>
      <li>
        The <code>$ACE_ROOT/bin/fuzz.pl</code> script has a sanity
        checking test for versioned namespaces that may be of use when
        debugging nested namespace issues, and for detecting
        <code>BEGIN</code>/<code>END</code> mismatches.
      </li>
    </ul>
    <p>
      Versioned namespace support in ACE may be enabled by adding
      <code>versioned_namespace=1</code> to your MPC
      <code><strong>default.features</strong></code> file.  Additional
information about versioned namespaces is available from the <A
HREF="http://www.riverace.com/newsletters/March2006.htm">Riverace
website</A>.
    </p>
    <hr>
    <address><a href="mailto:ossama@dre.vanderbilt.edu">Ossama Othman</a></address>
<!-- Created: Fri Mar 17 08:35:50 PST 2006 -->
<!-- hhmts start -->
Last modified: Fri Mar 17 20:47:41 PST 2006
<!-- hhmts end -->
  </body>
</html>