PageRenderTime 37ms CodeModel.GetById 12ms app.highlight 16ms RepoModel.GetById 2ms app.codeStats 0ms

/trunk/Doc/Manual/D.html

#
HTML | 454 lines | 309 code | 143 blank | 2 comment | 0 complexity | ed3e33e3fa90eb89141c28559b344556 MD5 | raw file
  1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2<html>
  3<head>
  4<title>SWIG and D</title>
  5<link rel="stylesheet" type="text/css" href="style.css">
  6<meta http-equiv="content-type" content="text/html; charset=UTF-8">
  7</head>
  8<body bgcolor="#FFFFFF">
  9<H1><a name="D"></a>21 SWIG and D</H1>
 10<!-- INDEX -->
 11<div class="sectiontoc">
 12<ul>
 13<li><a href="#D_introduction">Introduction</a>
 14<li><a href="#D_command_line_invocation">Command line invocation</a>
 15<li><a href="#D_typemaps">Typemaps</a>
 16<ul>
 17<li><a href="#D_typemap_name_comparison">C# &lt;-&gt; D name comparison</a>
 18<li><a href="#D_ctype_imtype_dtype">ctype, imtype, dtype</a>
 19<li><a href="#D_in_out_directorin_direcetorout">in, out, directorin, directorout</a>
 20<li><a href="#D_din_dout_ddirectorin_ddirectorout">din, dout, ddirectorin, ddirectorout</a>
 21<li><a href="#D_typecheck_typemaps">typecheck typemaps</a>
 22<li><a href="#D_code_injection_typemaps">Code injection typemaps</a>
 23<li><a href="#D_special_variables">Special variable macros</a>
 24</ul>
 25<li><a href="#D_features"><tt>%feature</tt>s</a>
 26<li><a href="#D_pragmas">Pragmas</a>
 27<li><a href="#D_exceptions">D Exceptions</a>
 28<li><a href="#D_directors">D Directors</a>
 29<li><a href="#D_other_features">Other features</a>
 30<ul>
 31<li><a href="#D_nspace">Extended namespace support (<tt>nspace</tt>)</a>
 32<li><a href="#D_native_pointer_support">Native pointer support</a>
 33<li><a href="#D_operator_overloading">Operator overloading</a>
 34<li><a href="#D_test_suite">Running the test-suite</a>
 35</ul>
 36<li><a href="#D_typemap_examples">D Typemap examples</a>
 37<li><a href="#D_planned_features">Work in progress and planned features</a>
 38</ul>
 39</div>
 40<!-- INDEX -->
 41
 42
 43
 44<H2><a name="D_introduction"></a>21.1 Introduction</H2>
 45
 46
 47<p>From the <a href="http://www.digitalmars.com/d/">D Programming Language</a> web site: <em>D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. [...] The D language is statically typed and compiles directly to machine code.</em> As such, it is not very surprising that D is able to directly <a href="http://www.digitalmars.com/d/1.0/interfaceToC.html">interface with C libraries</a>. Why would a SWIG module for D be needed then in the first place?</p>
 48
 49<p>Well, besides the obvious downside that the C header files have to be manually converted to D modules for this to work, there is one major inconvenience with this approach: D code usually is on a higher abstraction level than C, and many of the features that make D interesting are simply not available when dealing with C libraries, requiring you e.g. to manually convert strings between pointers to <tt>\0</tt>-terminated char arrays and D char arrays, making the algorithms from the D2 standard library unusable with C arrays and data structures, and so on.</p>
 50
 51<p>While these issues can be worked around relatively easy by hand-coding a thin wrapper layer around the C library in question, there is another issue where writing wrapper code per hand is not feasible: C++ libraries. D did not support interfacing to C++ in version 1 at all, and even if <tt>extern(C++)</tt> has been added to D2, the support is still very limited, and a custom wrapper layer is still required in many cases. </p>
 52
 53<p>To help addressing these issues, the SWIG C# module has been forked to support D. Is has evolved quite a lot since then, but there are still many similarities, so if you do not find what you are looking for on this page, it might be worth having a look at the chapter on <a href="CSharp.html">C#</a> (and also on <a href="Java.html">Java</a>, since the C# module was in turn forked from it).</p>
 54
 55
 56<H2><a name="D_command_line_invocation"></a>21.2 Command line invocation</H2>
 57
 58
 59<p>To activate the D module, pass the <tt>-d</tt> option to SWIG at the command line. The same standard command line switches as with any other language module are available, plus the following D specific ones:</p>
 60
 61<dl>
 62  <dt><tt>-d2</tt></dt>
 63  <dd>
 64    <p>By default, SWIG generates code for D1/Tango. Use the <tt>-d2</tt> flag to target D2/Phobos instead.</p>
 65  </dd>
 66
 67  <dt id="D_splitproxy"><tt>-splitproxy</tt></dt>
 68  <dd>
 69    <p>By default, SWIG generates two D modules: the <em>proxy</em> module, named like the source module (either specified via the <tt>%module</tt> directive or via the <tt>module</tt> command line switch), which contains all the proxy classes, functions, enums, etc., and the <em>intermediary</em> module (named like the proxy module, but suffixed with <tt>_im</tt>), which contains all the <tt>extern(C)</tt> function declarations and other private parts only used internally by the proxy module.</p>
 70    <p>If the split proxy mode is enabled by passing this switch at the command line, all proxy classes and enums are emitted to their own D module instead. The main proxy module only contains free functions and constants in this case.</p>
 71  </dd>
 72
 73  <dt><tt>-package &lt;pkg&gt;</tt></dt>
 74  <dd>
 75    <p>By default, the proxy D modules and the intermediary D module are written to the root package. Using this option, you can specify another target package instead.</p>
 76  </dd>
 77
 78  <dt><tt>-wrapperlibrary &lt;wl&gt;</tt></dt>
 79  <dd>
 80    <p>The code SWIG generates to dynamically load the C/C++ wrapper layer looks for a library called <tt>$module_wrap</tt> by default. With this switch, you can override the name of the file the wrapper code loads at runtime (the <tt>lib</tt> prefix and the suffix for shared libraries are appended automatically, depending on the OS).</p>
 81    <p>This might especially be useful if you want to invoke SWIG several times on separate modules, but compile the resulting code into a single shared library.</p>
 82  </dd>
 83</dl>
 84
 85
 86<H2><a name="D_typemaps"></a>21.3 Typemaps</H2>
 87
 88
 89<H3><a name="D_typemap_name_comparison"></a>21.3.1 C# &lt;-&gt; D name comparison</H3>
 90
 91
 92<p>If you already know the SWIG C# module, you might find the following name comparison table useful:</p>
 93
 94<div class="diagram"><pre>
 95 ctype                  &lt;-&gt;  ctype
 96 imtype                 &lt;-&gt;  imtype
 97 cstype                 &lt;-&gt;  dtype
 98 csin                   &lt;-&gt;  din
 99 csout                  &lt;-&gt;  dout
100 csdirectorin           &lt;-&gt;  ddirectorin
101 csdirectorout          &lt;-&gt;  ddirectorout
102 csinterfaces           &lt;-&gt;  dinterfaces
103 csinterfaces_derived   &lt;-&gt;  dinterfaces_derived
104 csbase                 &lt;-&gt;  dbase
105 csclassmodifiers       &lt;-&gt;  dclassmodifiers
106 cscode                 &lt;-&gt;  dcode
107 csimports              &lt;-&gt;  dimports
108 csbody                 &lt;-&gt;  dbody
109 csfinalize             &lt;-&gt;  ddestructor
110 csdestruct             &lt;-&gt;  ddispose
111 csdestruct_derived     &lt;-&gt;  ddispose_derived
112</pre></div>
113
114
115<H3><a name="D_ctype_imtype_dtype"></a>21.3.2 ctype, imtype, dtype</H3>
116
117
118<p>Mapping of types between the C/C++ library, the C/C++ library wrapper exposing the C functions, the D wrapper module importing these functions and the D proxy code.</p>
119
120<p>The <tt>ctype</tt> typemap is used to determine the types to use in the C wrapper functions. The types from the <tt>imtype</tt> typemap are used in the extern(C) declarations of these functions in the intermediary D module. The <tt>dtype</tt> typemap contains the D types used in the D proxy module/class.</p>
121
122
123<H3><a name="D_in_out_directorin_direcetorout"></a>21.3.3 in, out, directorin, directorout</H3>
124
125
126<p>Used for converting between the types for C/C++ and D when generating the code for the wrapper functions (on the C++ side).</p>
127
128<p>The code from the <tt>in</tt> typemap is used to convert arguments to the C wrapper function to the type used in the wrapped code (<tt>ctype</tt>->original C++ type), the <tt>out</tt> typemap is utilized to convert values from the wrapped code to wrapper function return types (original C++ type-><tt>ctype</tt>).</p>
129
130<p>The <tt>directorin</tt> typemap is used to convert parameters to the type used in the D director callback function, its return value is processed by <tt>directorout</tt> (see below).</p>
131
132
133<H3><a name="D_din_dout_ddirectorin_ddirectorout"></a>21.3.4 din, dout, ddirectorin, ddirectorout</H3>
134
135
136<p>Typemaps for code generation in D proxy and type wrapper classes.</p>
137
138<p id="D_din">The <tt>din</tt> typemap is used for converting function parameter types from the type used in the proxy module or class to the type used in the intermediary D module (the <a href="D.html#D_dinput"><tt>$dinput</tt></a> macro is replaced). To inject further parameter processing code before or after the call to the intermediary layer, the <tt>pre</tt>, <tt>post</tt> and <tt>terminator</tt> attributes can be used (please refer to the <a href="CSharp.html#CSharp_date_marshalling">C# date marshalling example</a> for more information on these).</p>
139
140<p id="D_dout">The <tt>dout</tt> typemap is used for converting function return values from the return type used in the intermediary D module to the type returned by the proxy function. The <tt>$excode</tt> special variable in <tt>dout</tt> typemaps is replaced by the <tt>excode</tt> typemap attribute code if the method can throw any exceptions from unmanaged code, otherwise by nothing (the <a href="D.html#D_imcall"><tt>$imcall</tt> and <tt>$owner</tt></a> macros are replaced).</p>
141
142<p id="D_ddirectorinout">The code from the <tt>ddirectorin</tt> and <tt>ddirectorout</tt> typemaps is used for conversion in director callback functions. Arguments are converted to the type used in the proxy class method they are calling by using the code from <tt>ddirectorin</tt>, the proxy class method return value is converted to the type the C++ code expects via the <tt>ddirectorout</tt> typemap (the <a href="D.html#D_dpcall"><tt>$dcall</tt> and <tt>$winput</tt></a> macros are replaced).</p>
143
144<p>The full chain of type conversions when a director callback is invoked looks like this:</p>
145
146 <div class="diagram"><pre>
147      type              CPPClass::method(type a)
148        &uarr;                       &darr;
149   &lt;directorout&gt;          &lt;directorin&gt;
150        &uarr;                       &darr;
151      ctype             methodCallback(ctype a)           C++
152 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
153      imtype            methodCallback(imtype a)           D
154        &uarr;                       &darr;
155  &lt;ddirectorout&gt;          &lt;ddirectorin&gt;
156        &uarr;                       &darr;
157      dtype             DClass.method(dtype a)</pre></div>
158
159
160<H3><a name="D_typecheck_typemaps"></a>21.3.5 typecheck typemaps</H3>
161
162
163<p>Because, unlike many scripting languages supported by SWIG, D does not need any dynamic dispatch helper to access an overloaded function, the purpose of these is merely to issue a warning for overloaded C++ functions that cannot be overloaded in D (as more than one C++ type maps to a single D type).</p>
164
165
166<H3><a name="D_code_injection_typemaps"></a>21.3.6 Code injection typemaps</H3>
167
168
169<p>These typemaps are used for generating the skeleton of proxy classes for C++ types.</p>
170
171<p>By overriding <tt>dbase</tt>, <tt>dinterfaces</tt> or <tt>dinterfaces_derived</tt>, the inheritance chain of the generated proxy class for a type can be modified. <tt>dclassmodifiers</tt> allows you to add any custom modifiers around the class keyword.</p>
172
173<p>Using <tt>dcode</tt> and <tt>dimports</tt>, you can specify additional D code which will be emitted into the class body respectively the imports section of the D module the class is written to.</p>
174
175<p id="D_class_code_typemaps"><tt>dconstructor</tt>, <tt>ddestructor</tt>, <tt>ddispose</tt> and <tt>ddispose_derived</tt> are used to generate the class constructor, destructor and <tt>dispose()</tt> method, respectively. The auxiliary code for handling the pointer to the C++ object is stored in <tt>dbody</tt> and <tt>dbody_derived</tt>. You can override them for specific types.</p>
176
177
178<H3><a name="D_special_variables"></a>21.3.7 Special variable macros</H3>
179
180
181<p>The standard SWIG special variables are available for use within typemaps as described in the <a href="Typemaps.html#Typemaps">Typemaps documentation</a>, for example <tt>$1</tt>, <tt>$input</tt>, <tt>$result</tt> etc.</p>
182
183<p>When generating D wrappers, a few additional macros are available:</p>
184<dl>
185  <dt><tt>$dclassname</tt> (C#: <tt>$csclassname</tt>)</dt>
186  <dd>
187    <p>This special variable works similar to <a href="Typemaps.html#Typemaps_special_variables"><tt>$n_type</tt></a> in that it returns the name of a type - it expands to the D proxy class name of the type being wrapped. If the type does not have an associated proxy class, it expands to the type wrapper class name, for example, <tt>SWIGTYPE_p_p_SomeCppClass</tt> is generated when wrapping <tt>SomeCppClass **</tt>.</p>
188    <p>There are two other variants available, <tt>$&amp;dclassname</tt> and <tt>$*dclassname</tt>. The former adds a level of indirection, while the latter removes one. For instance, when wrapping <tt>Foo **</tt>, <tt>$*dclassname</tt> would be replaced by the proxy class name corresponding to <tt>Foo *</tt>.</p>
189  </dd>
190
191  <dt><tt>$dclazzname</tt> (C#: <tt>$csclazzname</tt>)</dt>
192  <dd>
193    <p>This special variable expands the fully qualified C++ class into the package name, if used by the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt> feature</a>, and the proxy class name, mangled for use as a function name. For example, <tt>Namespace1::Namespace2::Klass</tt> is expanded into <tt>Namespace1_Namespace2_Klass_</tt>.</p>
194    <p>This special variable might be useful for calling certain functions in the wrapper layer (e.g. upcast wrappers) which are mangled like this.</p>
195  </dd>
196
197  <dt><tt>$null</tt></dt>
198  <dd><p>In code inserted into the generated C/C++ wrapper functions, this variable is replaced by either <tt>0</tt> or nothing at all, depending on whether the function has a return value or not. It can be used to bail out early e.g. in case of errors (<tt>return $null;</tt>).</p></dd>
199
200  <dt id="D_dinput"><tt>$dinput</tt> (C#: <tt>$csinput</tt>)</dt>
201  <dd>
202    <p>This variable is used in <tt><a href="D.html#D_din">din</a></tt> typemaps and is replaced by the expression which is to be passed to C/C++.</p>
203    <p>For example, this input</p>
204    <div class="code"><pre>
205%typemap(din) SomeClass * "SomeClass.getCPointer($dinput)"
206
207%inline %{
208  class SomeClass {};
209  void foo(SomeClass *arg);
210%}</pre></div>
211    <p>leads to the following D proxy code being generated:</p>
212<div class="targetlang"><pre>
213void foo(SomeClass arg) {
214  example_im.foo(SomeClass.getCPointer(arg));
215}</pre></div></dd>
216
217  <dt id="D_imcall"><tt>$imcall</tt> and <tt>$owner</tt> (C#: <tt>$imcall</tt>)</dt>
218  <dd>
219    <p>These variables are used in <tt><a href="D.html#D_dout">dout</a></tt> typemaps. <tt>$imcall</tt> contains the call to the intermediary module which provides the value to be used, and <tt>$owner</tt> signals if the caller is responsible for managing the object lifetime (that is, if the called method is a constructor or has been marked via <tt>%newobject</tt>).</p>
220    <p>Consider the following example:</p>
221<div class="code"><pre>
222%typemap(dout) SomeClass * {
223  return new SomeClass($imcall, $owner);
224}
225
226%inline %{
227  class SomeClass;
228  SomeClass *foo();
229
230  %newobject bar();
231  SomeClass *bar();
232%}</pre></div>
233   <p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like this:</p>
234<div class="targetlang"><pre>
235SomeClass foo() {
236  return new SomeClass(example_im.foo(), false);
237}
238
239SomeClass bar() {
240  return new SomeClass(example_im.bar(), true);
241}
242</pre></div>
243  </dd>
244
245  <dt><tt>$dcall</tt> and <tt>$winput</tt> (C#: <tt>$cscall</tt>, <tt>$iminput</tt>)</dt>
246  <dd id="D_dpcall"><p>These variables are used in the director-specific typemaps <a href="D.html#D_ddirectorinout"><tt>ddirectorin</tt></a> and <a href="D.html#D_ddirectorinout"><tt>ddirectorout</tt></a>. They are more or less the reverse of the <tt>$imcall</tt> and <tt>$dinput</tt> macros: <tt>$dcall</tt> contains the invocation of the D proxy method of which the return value is to be passed back to C++, <tt>$winput</tt> contains the parameter value from C++.</p></dd>
247
248  <dt><tt>$excode</tt></dt>
249  <dd><p>This variable is used in <tt>dout</tt> and <tt>dconstructor</tt> typemaps and is filled with the contents of the <tt>excode</tt> typemap attribute if an exception could be thrown from the C++ side. See the <a href="CSharp.html#CSharp_exceptions">C# documentation</a> for details.</p></dd>
250
251  <dt><tt>$dbaseclass</tt></dt>
252  <dd><p>Currently for internal use only, it contains the D name of the C++ base class (if any) inside proxy classes.</p></dd>
253
254  <dt><tt>$directorconnect</tt></dt>
255  <dd>
256    <p>This macro is only valid inside the <tt><a href="D.html#D_class_code_typemaps">dconstructor</a></tt> typemap and contains the value of the <tt>dconstructor</tt> typemap attribute if the currently wrapped class has directors enabled.</p>
257    <p>This is how the default <tt>dconstructor</tt> typemap looks like (you usually do not want to specify a custom one):</p>
258<div class="code"><pre>
259%typemap(dconstructor, excode=SWIGEXCODE,
260         directorconnect="\n  swigDirectorConnect();") SWIGTYPE {
261  this($imcall, true);$excode$directorconnect
262}
263</pre></div>
264  </dd>
265
266  <dt id="D_importtype"><tt>$importtype(SomeDType)</tt></dt>
267  <dd>
268    <p>This macro is used in the <tt>dimports</tt> typemap if a dependency on another D type generated by SWIG is added by a custom typemap.</p>
269    <p>Consider the following code snippet:</p>
270<div class="code"><pre>
271%typemap(dinterfaces) SomeClass "AnInterface, AnotherInterface";
272</pre></div>
273    <p>This causes SWIG to add <tt>AnInterface</tt> and <tt>AnotherInterface</tt> to the base class list of <tt>SomeClass</tt>:</p>
274<div class="targetlang"><pre>
275class SomeClass : AnInterface, AnotherInterface {
276  ...
277}
278</pre></div>
279    <p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt> have to be in scope. If SWIG is not in split proxy mode, this is already the case, but it it is, they have to be added to the import list via the <tt>dimports</tt> typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.</p>
280    <p>The <tt>$importtype</tt> macro helps you to elegantly solve this problem:</p>
281<div class="code"><pre>
282%typemap(dimports) RemoteMpe %{
283$importtype(AnInterface)
284$importtype(AnotherInterface)
285%}
286</pre></div>
287    <p>If SWIG is in split proxy mode, it expands to an <tt>import</tt> statement for the specified type, to nothing if not.</p>
288  </dd>
289
290  <dt><tt>$module</tt></dt>
291  <dd><p>Expands to the name of the main proxy D module.</p></dd>
292
293  <dt><tt>$imdmodule</tt></dt>
294  <dd><p>Contains the fully qualified name of the intermediary D module.</p></dd>
295</dl>
296
297
298<H2><a name="D_features"></a>21.4 <tt>%feature</tt>s</H2>
299
300
301<p>The D module defines a number of directives which modify the <a href="Customization.html#Customization_features">SWIG features</a> set globally or for a specific declaration:</p>
302
303
304<dl>
305  <dt><tt>%dmanifestconst</tt> and <tt>%dconstvalue(value)</tt></dt>
306  <dd>
307    <p>Out of the box, SWIG generates accessor methods for C <tt>#defines</tt> and C++ constants. The <tt>%dmanifestconst</tt> directive enables wrapping these constants as D manifest constants (<tt>const</tt> in D1, <tt>enum</tt> in D2).</p>
308    <p>For this to work, the C/C++ code for the constant value must directly compile as D code, though. If this is not the case, you can manually override the expression written to the D proxy module using the <tt>%dconstvalue</tt> directive, passing the new value as parameter.</p>
309    <p>For <tt>enum</tt>s, again <tt>%dconstvalue</tt> can be used to override the value of an enum item if the initializer should not compile in D.</p>
310  </dd>
311
312  <dt><tt>%dmethodmodifiers</tt></dt>
313  <dd>
314    <p>This directive can be used to override the modifiers for a proxy function. For instance, you could make a <tt>public</tt> C++ member function <tt>private</tt> in D like this:</p>
315<div class="code"><pre>
316%dmethodmodifiers A::foo "private";
317
318%inline %{
319struct A {
320  void foo();
321};
322%}
323</pre></div>
324  </dd>
325</dl>
326
327
328<H2><a name="D_pragmas"></a>21.5 Pragmas</H2>
329
330
331<p>There are a few SWIG pragmas specific to the D module, which you can use to influence the D code SWIG generates:</p>
332
333<dl>
334  <dt><tt>%pragma(d) imdmodulecode</tt></dt>
335  <dd><p>The passed text (D code) is copied verbatim to the intermediary D module. For example, it can be (and is, internally) used to emit additional private helper code for the use by proxy typemaps.</p></dd>
336
337  <dt><tt>%pragma(d) imdmoduleimports</tt></dt>
338  <dd><p>Additional code to be emitted to the imports section of the intermediary D module (the <a href="D.html#D_importtype">$importtype</a> macro can be used here). You probably want to use this in conjunction with the <tt>imdmodulecode</tt> pragma.</p></dd>
339
340  <dt><tt>%pragma(d) proxydmodulecode</tt></dt>
341  <dd><p>Just like <tt>proxydmodulecode</tt>, the argument is copied to the proxy D module (if SWIG is in <a href="D.html#D_splitproxy">split proxy mode</a> and/or the <tt>nspace</tt> feature is used, it is emitted to the main proxy D module only).</p></dd>
342
343  <dt><tt>%pragma(d) globalproxyimports</tt></dt>
344  <dd>
345    <p>The D module currently does not support specifying dependencies on external modules (e.g. from the standard library) for the D typemaps. To add the import statements to the proxy modules (resp. to <em>all</em> proxy modules if in split proxy mode), you can use the <tt>globalproxyimports</tt> directive.</p>
346    <p>For example:</p>
347<div class="code"><pre>
348%typemap(din) char[] "($dinput ? tango.stdc.stringz.toStringz($dinput) : null)"
349%pragma(d) globalproxyimports = "static import tango.stdc.stringz;";
350</pre></div>
351  </dd>
352
353  <dt><tt>%pragma(d) wrapperloadercode</tt></dt>
354  <dd>
355    <p>The D code for loading the wrapper library (it is copied to the intermediary D module). The <tt>$wrapperloaderbindcode</tt> variable is replaced by the list of commands for binding the functions from the wrapper library to the symbols in the intermediary D module.</p>
356    <p>Each time this pragma is specified, the previous value is overwritten.</p>
357  </dd>
358
359  <dt><tt>%pragma(d) wrapperloaderbindcommand</tt></dt>
360  <dd>
361    <p>The D command to use for binding the wrapper functions from the C/C++ library to the symbols in the intermediary D module. The <tt>$function</tt> variable contains the name of the D function in the wrap module, the <tt>$symbol</tt> variable is replaced by the name of the symbol in the library.</p>
362    <p>Each time this pragma is specified, the previous value is overwritten.</p>
363  </dd>
364</dl>
365
366
367<H2><a name="D_exceptions"></a>21.6 D Exceptions</H2>
368
369
370<p>Out of the box, C++ exceptions are fundamentally incompatible to their equivalent in the D world and cannot simply be propagated to a calling D method. There is, however, an easy way to solve this problem: Just catch the exception in the C/C++ wrapper layer, pass the contents to D, and make the wrapper code rethrow the exception in the D world.</p>
371
372<p>The implementation details of this are a bit crude, but the SWIG D module automatically takes care of this, as long as it is able to detect that an exception could potentially be thrown (e.g. because the C++ method has a <tt>throw(...)</tt> exception specification).</p>
373
374<p>As this feature is implemented in exactly the same way it is for C#, please see the <a href="CSharp.html#CSharp_exceptions">C# documentation</a> for a more detailed explanation.</p>
375
376
377<H2><a name="D_directors"></a>21.7 D Directors</H2>
378
379
380<p>When the directors feature is activated, SWIG generates extra code on both the C++ and the D side to enable cross-language polymorphism. Essentially, this means that if you subclass a proxy class in D, C++ code can access any overridden virtual methods just as if you created a derived class in C++.</p>
381
382<p>There is no D specific documentation yet, but the way the feature is implemented is very similar to how it is done in <a href="Java.html#Java_directors">Java</a> and <a href="CSharp.html#CSharp_directors">C#</a>.
383</p>
384
385
386<H2><a name="D_other_features"></a>21.8 Other features</H2>
387
388
389<H3><a name="D_nspace"></a>21.8.1 Extended namespace support (<tt>nspace</tt>)</H3>
390
391
392<p>By default, SWIG flattens all C++ namespaces into a single target language namespace, but as for Java and C#, the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature is supported for D. If it is active, C++ namespaces are mapped to D packages/modules. Note, however, that like for the other languages, <em>free</em> variables and functions are not supported yet; currently, they are all allows written to the main proxy D module.</p>
393
394
395<H3><a name="D_native_pointer_support"></a>21.8.2 Native pointer support</H3>
396
397
398<p>Contrary to many of the scripting languages supported by SWIG, D fully supports C-style pointers. The D module thus includes a custom mechanism to wrap C pointers directly as D pointers where applicable, that is, if the type that is pointed to is represented the same in C and D (on the bit-level), dubbed a <em>primitive type</em> below.</p>
399
400<p>Central to this custom pointer handling scheme are two typemap attributes: the <tt>cprimitive</tt> attribute on the <tt>dtype</tt> typemap and the <tt>nativepointer</tt> attribute on all the typemaps which influence the D side of the code (<tt>dtype</tt>, <tt>din</tt>, <tt>dout</tt>, ...). When a D typemap is looked up, the following happens behind the scenes:</p>
401
402<p>First, the matching typemap is determined by the usual typemap lookup rules. Then, it is checked if the result has the <tt>nativepointer</tt> attribute set. If it is present, it means that its value should replace the typemap value <em>if and only if</em> the actual type the typemap is looked up for is a primitive type, a pointer to a primitive type (through an arbitrary level of indirections), or a function pointer with only primitive types in its signature.</p>
403
404<p>To determine if a type should be considered primitive, the <tt>cprimitive</tt> attribute on its <tt>dtype</tt> attribute is used. For example, the <tt>dtype</tt> typemap for <tt>float</tt> has <tt>cprimitive="1"</tt>, so the code from the <tt>nativepointer</tt> attribute is taken into account e.g. for <tt>float **</tt> or the function pointer <tt>float (*)(float *)</tt>.</p>
405
406
407<H3><a name="D_operator_overloading"></a>21.8.3 Operator overloading</H3>
408
409
410<p>The D module comes with basic operator overloading support for both D1 and D2. There are, however, a few limitations arising from conceptual differences between C++ and D:</p>
411
412<p>The first key difference is that C++ supports free functions as operators (along with argument-dependent lookup), while D requires operators to be member functions of the class they are operating on. SWIG can only automatically generate wrapping code for member function operators; if you want to use operators defined as free functions in D, you need to handle them manually.</p>
413
414<p>Another set of differences between C++ and D concerns individual operators. For example, there are quite a few operators which are overloadable in C++, but not in D, for example <tt>&amp;&amp;</tt> and <tt>||</tt>, but also <tt>!</tt>, and prefix increment/decrement operators in <a href="http://www.digitalmars.com/d/1.0/operatoroverloading.html">D1</a> resp. their postfix pendants in <a href="http://www.digitalmars.com/d/2.0/operatoroverloading.html">D2</a>.</p>
415
416<p>There are also some cases where the operators can be translated to D, but the differences in the implementation details are big enough that a rather involved scheme would be required for automatic wrapping them, which has not been implemented yet. This affects, for example, the array subscript operator, <tt>[]</tt>, in combination with assignments - while <tt>operator []</tt> in C++ simply returns a reference which is then written to, D resorts to a separate <tt>opIndexAssign</tt> method -, or implicit casting (which was introduced in D2 via <tt>alias this</tt>). Despite the lack of automatic support, manually handling these cases should be perfectly possible.</p>
417
418
419<H3><a name="D_test_suite"></a>21.8.4 Running the test-suite</H3>
420
421
422<p>As with any other language, the SWIG test-suite can be built for D using the <tt>*-d-test-suite</tt> targets of the top-level Makefile. By default, D1 is targeted, to build it with D2, use the optional <tt>D_VERSION</tt> variable, e.g. <tt>make check-d-test-suite D_VERSION=2</tt>.</p>
423
424<p>Note: If you want to use GDC on Linux or another platform which requires you to link <tt>libdl</tt> for dynamically loading the shared library, you might have to add <tt>-ldl</tt> manually to the <tt>d_compile</tt> target in <tt>Examples/Makefile</tt>, because GDC does not currently honor the <tt>pragma(lib,...)</tt> statement.</p>
425
426
427<H2><a name="D_typemap_examples"></a>21.9 D Typemap examples</H2>
428
429
430<p>There are no D-specific typemap examples yet. However, with the above <a href="D.html#D_typemap_name_comparison">name comparison table</a>, you should be able to get an idea what can be done by looking at the <a href="CSharp.html#CSharp_typemap_examples">corresponding C# section</a>.</p>
431
432
433
434<H2><a name="D_planned_features"></a>21.10 Work in progress and planned features</H2>
435
436
437<p>There are a couple of features which are not implemented yet, but would be very useful and might be added in the near future:</p>
438
439<ul>
440  <li><em>Static linking:</em> Currently, the C wrapper code is compiled into a dynamic library, out of which the symbol addresses are looked up at runtime by the D part. If statically linking the different languages into one binary was supported, a tool-chain capable of performing IPO at link time could inline the wrapping code, effectively reducing the overhead for simple calls to zero.</li>
441  <li><em>C array handling:</em> Many data structures in some C/C++ libraries contain array containing of a pointer to the first element and the element count. Currently, one must manually writing wrapper code to be able to access these from D. It should be possible to add a set of SWIG macros to semi-automatically generate conversion code.</li>
442</ul>
443
444<p>Some generated code might also be a bit rough around the edges, particularly in the following areas:</p>
445
446<ul>
447  <li><em>Memory management:</em> Although the currently generated wrapper code works fine with regard to the GC for the test-suite, there might be issues coming up in real-world multi-threaded usage.</li>
448  <li><em>D2 support</em>: Originally, the module has been developed for the use with D1, D2/Phobos support has been added in later. The basic features should work equally well for both, but there <em>could</em> be issues concerning const-correctness etc.</li>
449</ul>
450
451
452</body>
453</html>
454