root/trunk/docsrc/cpp_interface.dd

Revision 659, 11.7 kB (checked in by andrei, 4 years ago)

Changed ddoc extensions to dd and changed linux.mak accordingly

  • Property svn:eol-style set to native
Line 
1 Ddoc
2
3 $(SPEC_S Interfacing to C++,
4
5     $(P
6     While D is fully capable of
7     $(LINK2 interfaceToC.html, interfacing to C),
8     its ability to interface to C++ is much more limited.
9     There are three ways to do it:
10     )
11
12     $(OL
13
14     $(LI Use C++'s ability to create a C interface, and then
15     use D's ability to
16     $(LINK2 interfaceToC.html, interface with C)
17     to access that interface.
18     )
19
20     $(LI Use C++'s ability to create a COM interface, and then
21     use D's ability to
22     $(LINK2 COM.html, interface with COM)
23     to access that interface.
24     )
25
26     $(LI Use the limited ability described here to connect
27     directly to C++ functions and classes.
28     )
29
30     )
31
32 <h2>The General Idea</h2>
33
34     $(P Being 100% compatible with C++ means more or less adding
35     a fully functional C++ compiler front end to D.
36     Anecdotal evidence suggests that writing such is a minimum
37     of a 10 man-year project, essentially making a D compiler
38     with such capability unimplementable.
39     Other languages looking to hook up to C++ face the same
40     problem, and the solutions have been:
41     )
42
43     $(OL
44     $(LI Support the COM interface (but that only works for Windows).)
45     $(LI Laboriously construct a C wrapper around
46     the C++ code.)
47     $(LI Use an automated tool such as SWIG to construct a
48     C wrapper.)
49     $(LI Reimplement the C++ code in the other language.)
50     $(LI Give up.)
51     )
52
53     $(P D takes a pragmatic approach that assumes a couple
54     modest accommodations can solve a significant chunk of
55     the problem:
56     )
57
58     $(UL
59     $(LI matching C++ name mangling conventions)
60     $(LI matching C++ function calling conventions)
61     $(LI matching C++ virtual function table layout for single inheritance)
62     )
63
64 <h2>Calling C++ Global Functions From D</h2>
65
66     $(P Given a C++ function in a C++ source file:)
67
68 $(CPPCODE
69 #include &lt;iostream&gt;
70
71 using namespace std;
72
73 int foo(int i, int j, int k)
74 {
75     cout &lt;&lt; "i = " &lt;&lt; i &lt;&lt; endl;
76     cout &lt;&lt; "j = " &lt;&lt; j &lt;&lt; endl;
77     cout &lt;&lt; "k = " &lt;&lt; k &lt;&lt; endl;
78
79     return 7;
80 }
81 )
82
83     $(P In the corresponding D code, $(CODE foo)
84     is declared as having C++ linkage and function calling conventions:
85     )
86
87 ------
88 extern (C++) int foo(int i, int j, int k);
89 ------
90
91     $(P and then it can be called within the D code:)
92
93 ------
94 extern (C++) int foo(int i, int j, int k);
95
96 void main()
97 {
98     foo(1,2,3);
99 }
100 ------
101
102     $(P Compiling the two files, the first with a C++ compiler,
103     the second with a D compiler, linking them together,
104     and then running it yields:)
105
106 $(CONSOLE
107 i = 1
108 j = 2
109 k = 3
110 )
111
112     $(P There are several things going on here:)
113
114     $(UL
115     $(LI D understands how C++ function names are "mangled" and the
116     correct C++ function call/return sequence.)
117
118     $(LI Because modules are not part of C++, each function with
119     C++ linkage must be globally unique within the program.)
120
121     $(LI There are no __cdecl, __far, __stdcall, __declspec, or other
122     such nonstandard C++ extensions in D.)
123
124     $(LI There are no volatile type modifiers in D.)
125
126     $(LI Strings are not 0 terminated in D. See "Data Type Compatibility"
127     for more information about this. However, string literals in D are
128     0 terminated.)
129
130     )
131
132     $(P C++ functions that reside in namespaces cannot be
133     direcly called from D.
134     )
135
136
137 <h2>Calling Global D Functions From C++</h2>
138
139     $(P To make a D function accessible from C++, give it
140     C++ linkage:)
141
142 ---
143 import std.stdio;
144
145 extern (C++) int foo(int i, int j, int k)
146 {
147     writefln("i = %s", i);
148     writefln("j = %s", j);
149     writefln("k = %s", k);
150     return 1;
151 }
152
153 extern (C++) void bar();
154
155 void main()
156 {
157     bar();
158 }
159 ---
160
161     $(P The C++ end looks like:)
162
163 $(CPPCODE
164 int foo(int i, int j, int k);
165
166 void bar()
167 {
168     foo(6, 7, 8);
169 }
170 )
171
172     $(P Compiling, linking, and running produces the output:)
173
174 $(CONSOLE
175 i = 6
176 j = 7
177 k = 8
178 )
179
180
181 <h2>Classes</h2>
182
183     $(P D classes are singly rooted by Object, and have an
184     incompatible layout from C++ classes.
185     D interfaces, however, are very similar to C++ single
186     inheritance class heirarchies.
187     So, a D interface with the attribute of $(CODE extern (C++))
188     will have a virtual function pointer table (vtbl[]) that
189     exactly matches C++'s.
190     A regular D interface has a vtbl[] that differs in that
191     the first entry in the vtbl[] is a pointer to D's RTTI info,
192     whereas in C++ the first entry points to the first virtual
193     function.
194     )
195
196 <h2>Calling C++ Virtual Functions From D</h2>
197
198     $(P Given C++ source code defining a class like:)
199
200 $(CPPCODE
201 #include &lt;iostream&gt;
202
203 using namespace std;
204
205 class D
206 {
207   public:
208     virtual int bar(int i, int j, int k)
209     {
210     cout &lt;&lt; "i = " &lt;&lt; i &lt;&lt; endl;
211     cout &lt;&lt; "j = " &lt;&lt; j &lt;&lt; endl;
212     cout &lt;&lt; "k = " &lt;&lt; k &lt;&lt; endl;
213     return 8;
214     }
215 };
216
217 D *getD()
218 {
219     D *d = new D();
220     return d;
221 }
222 )
223
224     $(P We can get at it from D code like:)
225
226 ---
227 extern (C++)
228 {
229   interface D
230   {
231     int bar(int i, int j, int k);
232   }
233
234   D getD();
235 }
236
237 void main()
238 {
239     D d = getD();
240     d.bar(9,10,11);
241 }
242 ---
243
244 <h2>Calling D Virtual Functions From C++</h2>
245
246     $(P Given D code like:)
247
248 ---
249 extern (C++) int callE(E);
250
251 extern (C++) interface E
252 {
253     int bar(int i, int j, int k);
254 }
255
256 class F : E
257 {
258     extern (C++) int bar(int i, int j, int k)
259     {
260     writefln("i = ", i);
261     writefln("j = ", j);
262     writefln("k = ", k);
263     return 8;
264     }
265 }
266
267 void main()
268 {
269     F f = new F();
270     callE(f);
271 }
272 ---
273
274     $(P The C++ code to access it looks like:)
275
276 $(CPPCODE
277 class E
278 {
279   public:
280     virtual int bar(int i, int j, int k);
281 };
282
283
284 int callE(E *e)
285 {
286     return e->bar(11,12,13);
287 }
288 )
289
290     $(P Note:)
291
292     $(UL
293     $(LI non-virtual functions, and static member functions,
294     cannot be accessed.)
295
296     $(LI class fields can only be accessed via virtual getter
297     and setter methods.)
298     )
299
300 <h2>Function Overloading</h2>
301
302     $(P C++ and D follow different rules for function overloading.
303     D source code, even when calling $(CODE extern (C++)) functions,
304     will still follow D overloading rules.
305     )
306
307
308 <h2>Storage Allocation</h2>
309
310     $(P C++ code explicitly manages memory with calls to
311     $(CODE ::operator new()) and $(CODE ::operator delete()).
312     D allocates memory using the D garbage collector,
313     so no explicit delete's are necessary.
314     D's new and delete are not compatible with C++'s
315     $(CODE ::operator new) and $(CODE::operator delete).
316     Attempting to allocate memory with C++ $(CODE ::operator new)
317     and deallocate it with D's $(CODE delete), or vice versa, will
318     result in miserable failure.
319     )
320
321     $(P D can still explicitly allocate memory using std.c.stdlib.malloc()
322     and std.c.stdlib.free(), these are useful for connecting to C++
323     functions that expect malloc'd buffers, etc.
324     )
325
326     $(P If pointers to D garbage collector allocated memory are passed to
327     C++ functions, it's critical to ensure that that memory will not
328     be collected by the garbage collector before the C++ function is
329     done with it. This is accomplished by:
330     )
331
332     $(UL
333
334     $(LI Making a copy of the data using std.c.stdlib.malloc() and passing
335     the copy instead.)
336
337     $(LI Leaving a pointer to it on the stack (as a parameter or
338     automatic variable), as the garbage collector will scan the stack.)
339
340     $(LI Leaving a pointer to it in the static data segment, as the
341     garbage collector will scan the static data segment.)
342
343     $(LI Registering the pointer with the garbage collector with the
344     std.gc.addRoot() or std.gc.addRange() calls.)
345
346     )
347
348     $(P An interior pointer to the allocated memory block is sufficient
349     to let the GC
350     know the object is in use; i.e. it is not necessary to maintain
351     a pointer to the beginning of the allocated memory.
352     )
353
354     $(P The garbage collector does not scan the stacks of threads not
355     created by the D Thread interface. Nor does it scan the data
356     segments of other DLL's, etc.
357     )
358
359 <h2>Data Type Compatibility</h2>
360
361     $(TABLE1
362     <caption>D And C Type Equivalence</caption>
363
364     $(TR
365     $(TH D type)
366     $(TH C type)
367     )
368
369     $(TR
370     $(TD $(B void))
371     $(TD $(B void))
372     )
373
374     $(TR
375     $(TD $(B byte))
376     $(TD $(B signed char))
377     )
378
379     $(TR
380     $(TD $(B ubyte))
381     $(TD $(B unsigned char))
382     )
383
384     $(TR
385     $(TD $(B char))
386     $(TD $(B char) (chars are unsigned in D))
387     )
388
389     $(TR
390     $(TD $(B wchar))
391     $(TD $(B wchar_t) (when sizeof(wchar_t) is 2))
392     )
393
394     $(TR
395     $(TD $(B dchar))
396     $(TD $(B wchar_t) (when sizeof(wchar_t) is 4))
397     )
398
399     $(TR
400     $(TD $(B short))
401     $(TD $(B short))
402     )
403
404     $(TR
405     $(TD $(B ushort))
406     $(TD $(B unsigned short))
407     )
408
409     $(TR
410     $(TD $(B int))
411     $(TD $(B int))
412     )
413
414     $(TR
415     $(TD $(B uint))
416     $(TD $(B unsigned))
417     )
418
419     $(TR
420     $(TD $(B long))
421     $(TD $(B long long))
422     )
423
424     $(TR
425     $(TD $(B ulong))
426     $(TD $(B unsigned long long))
427     )
428
429     $(TR
430     $(TD $(B float))
431     $(TD $(B float))
432     )
433
434     $(TR
435     $(TD $(B double))
436     $(TD $(B double))
437     )
438
439     $(TR
440     $(TD $(B real))
441     $(TD $(B long double))
442     )
443
444     $(TR
445     $(TD $(B ifloat))
446     $(TD no equivalent)
447     )
448
449     $(TR
450     $(TD $(B idouble))
451     $(TD no equivalent)
452     )
453
454     $(TR
455     $(TD $(B ireal))
456     $(TD no equivalent)
457     )
458
459     $(TR
460     $(TD $(B cfloat))
461     $(TD no equivalent)
462     )
463
464     $(TR
465     $(TD $(B cdouble))
466     $(TD no equivalent)
467     )
468
469     $(TR
470     $(TD $(B creal))
471     $(TD no equivalent)
472     )
473
474     $(TR
475     $(TD $(B struct))
476     $(TD $(B struct))
477     )
478
479     $(TR
480     $(TD $(B union))
481     $(TD $(B union))
482     )
483
484     $(TR
485     $(TD $(B enum))
486     $(TD $(B enum))
487     )
488
489     $(TR
490     $(TD $(B class))
491     $(TD no equivalent)
492     )
493
494     $(TR
495     $(TD $(I type)$(B *))
496     $(TD $(I type) $(B *))
497     )
498
499     $(TR
500     $(TD no equivalent)
501     $(TD $(I type) $(B &amp;))
502     )
503
504     $(TR
505     $(TD $(I type)$(B [)$(I dim)$(B ]))
506     $(TD $(I type)$(B [)$(I dim)$(B ]))
507     )
508
509     $(TR
510     $(TD $(I type)$(B [)$(I dim)$(B ]*))
511     $(TD $(I type)$(B (*)[)$(I dim)$(B ]))
512     )
513
514     $(TR
515     $(TD $(I type)$(B []))
516     $(TD no equivalent)
517     )
518
519     $(TR
520     $(TD $(I type)$(B [)$(I type)$(B ]))
521     $(TD no equivalent)
522     )
523
524     $(TR
525     $(TD $(I type) $(B function)$(B $(LPAREN))$(I parameters)$(B $(RPAREN)))
526     $(TD $(I type)$(B (*))$(B $(LPAREN))$(I parameters)$(B $(RPAREN)))
527     )
528
529     $(TR
530     $(TD $(I type) $(B delegate)$(B $(LPAREN))$(I parameters)$(B $(RPAREN)))
531     $(TD no equivalent)
532     )
533
534     )
535
536     $(P These equivalents hold for most 32 bit C++ compilers.
537     The C++ standard
538     does not pin down the sizes of the types, so some care is needed.
539     )
540
541 <h2>Structs and Unions</h2>
542
543     $(P D structs and unions are analogous to C's.
544     )
545
546     $(P C code often adjusts the alignment and packing of struct members
547     with a command line switch or with various implementation specific
548     #pragma's. D supports explicit alignment attributes that correspond
549     to the C compiler's rules. Check what alignment the C code is using,
550     and explicitly set it for the D struct declaration.
551     )
552
553     $(P D does not support bit fields. If needed, they can be emulated
554     with shift and mask operations.
555     $(LINK2 htod.html, htod) will convert bit fields to inline functions that
556     do the right shift and masks.
557     )
558
559 <h2>Object Construction and Destruction</h2>
560
561     $(P Similarly to storage allocation and deallocation, objects
562     constructed in D code should be destructed in D,
563     and objects constructed
564     in C++ should be destructed in C++ code.
565     )
566
567 <h2>Special Member Functions</h2>
568
569     $(P D cannot call C++ special member functions, and vice versa.
570     These include constructors, destructors, conversion operators,
571     operator overloading, and allocators.
572     )
573
574 <h2>Runtime Type Identification</h2>
575
576     $(P D runtime type identification
577     uses completely different techniques than C++.
578     The two are incompatible.)
579
580 <h2>C++ Class Objects by Value</h2>
581
582     $(P D can access POD (Plain Old Data) C++ structs, and it can
583     access C++ class virtual functions by reference.
584     It cannot access C++ classes by value.
585     )
586
587 <h2>C++ Templates</h2>
588
589     $(P D templates have little in common with C++ templates,
590     and it is very unlikely that any sort of reasonable method
591     could be found to express C++ templates in a link-compatible
592     way with D.
593     )
594
595     $(P This means that the C++ STL, and C++ Boost, likely will
596     never be accessible from D.
597     )
598
599 <h2>Exception Handling</h2>
600
601     $(P D and C++ exception handling are completely different.
602     Throwing exceptions across the boundaries between D
603     and C++ code will likely not work.
604     )
605
606 <h2>Future Developments</h2>
607
608     $(P How the upcoming C++0x standard will affect this is not
609     known.)
610
611     $(P Over time, more aspects of the C++ ABI may be accessible
612     directly from D.)
613
614 )
615
616 Macros:
617     TITLE=Interfacing to C++
618     WIKI=InterfaceToCPP
Note: See TracBrowser for help on using the browser.