root/trunk/docsrc/interfaceToC.dd

Revision 1398, 8.1 kB (checked in by walter, 2 years ago)

clarified how to pass arrays to C functions

  • Property svn:eol-style set to native
Line 
1 Ddoc
2
3 $(SPEC_S Interfacing to C,
4
5     $(P D is designed to fit comfortably with a C compiler for the target
6     system. D makes up for not having its own VM by relying on the
7     target environment's C runtime library. It would be senseless to
8     attempt to port to D or write D wrappers for the vast array of C APIs
9     available. How much easier it is to just call them directly.
10     )
11
12     $(P This is done by matching the C compiler's data types, layouts,
13     and function call/return sequences.
14     )
15
16 <h2>Calling C Functions</h2>
17
18     $(P C functions can be called directly from D. There is no need for
19     wrapper functions, argument swizzling, and the C functions do not
20     need to be put into a separate DLL.
21     )
22
23     $(P The C function must be declared and given a calling convention,
24     most likely the "C" calling convention, for example:
25     )
26
27 ------
28 extern (C) int strcmp(char* string1, char* string2);
29 ------
30
31     $(P and then it can be called within D code in the obvious way:)
32
33 ------
34 import std.string;
35 int myDfunction(char[] s)
36 {
37     return strcmp(std.string.toStringz(s), "foo");
38 }
39 ------
40
41     $(P There are several things going on here:)
42
43     $(UL
44     $(LI D understands how C function names are "mangled" and the
45     correct C function call/return sequence.)
46
47     $(LI C functions cannot be overloaded with another C function
48     with the same name.)
49
50     $(LI There are no __cdecl, __far, __stdcall, __declspec, or other
51     such C type modifiers in D. These are handled by attributes, such
52     as $(TT extern (C)).)
53
54     $(LI There are no const or volatile type modifiers in D. To declare
55     a C function that uses those type modifiers, just drop those
56     keywords from the declaration.)
57
58     $(LI Strings are not 0 terminated in D. See "Data Type Compatibility"
59     for more information about this. However, string literals in D are
60     0 terminated.)
61
62     )
63
64     $(P C code can correspondingly call D functions, if the D functions
65     use an attribute that is compatible with the C compiler, most likely
66     the extern (C):)
67
68 ------
69 // myfunc() can be called from any C function
70 extern (C)
71 {
72     void myfunc(int a, int b)
73     {
74     ...
75     }
76 }
77 ------
78
79 <h2>Storage Allocation</h2>
80
81     $(P C code explicitly manages memory with calls to malloc() and
82     free(). D allocates memory using the D garbage collector,
83     so no explicit free's are necessary.
84     )
85
86     $(P D can still explicitly allocate memory using std.c.stdlib.malloc()
87     and std.c.stdlib.free(), these are useful for connecting to C
88     functions that expect malloc'd buffers, etc.
89     )
90
91     $(P If pointers to D garbage collector allocated memory are passed to
92     C functions, it's critical to ensure that that memory will not
93     be collected by the garbage collector before the C function is
94     done with it. This is accomplished by:
95     )
96
97     $(UL
98
99     $(LI Making a copy of the data using std.c.stdlib.malloc() and passing
100     the copy instead.)
101
102     $(LI Leaving a pointer to it on the stack (as a parameter or
103     automatic variable), as the garbage collector will scan the stack.)
104
105     $(LI Leaving a pointer to it in the static data segment, as the
106     garbage collector will scan the static data segment.)
107
108     $(LI Registering the pointer with the garbage collector with the
109     std.gc.addRoot() or std.gc.addRange() calls.)
110
111     )
112
113     $(P An interior pointer to the allocated memory block is sufficient
114     to let the GC
115     know the object is in use; i.e. it is not necessary to maintain
116     a pointer to the beginning of the allocated memory.
117     )
118
119     $(P The garbage collector does not scan the stacks of threads not
120     created by the D Thread interface. Nor does it scan the data
121     segments of other DLL's, etc.
122     )
123
124 <h2>Data Type Compatibility</h2>
125
126     $(TABLE1
127     <caption>D And C Type Equivalence</caption>
128
129     $(TR
130     $(TH D type)
131     $(TH C type)
132     )
133
134     $(TR
135     $(TD $(B void))
136     $(TD $(B void))
137     )
138
139     $(TR
140     $(TD $(B byte))
141     $(TD $(B signed char))
142     )
143
144     $(TR
145     $(TD $(B ubyte))
146     $(TD $(B unsigned char))
147     )
148
149     $(TR
150     $(TD $(B char))
151     $(TD $(B char) (chars are unsigned in D))
152     )
153
154     $(TR
155     $(TD $(B wchar))
156     $(TD $(B wchar_t) (when sizeof(wchar_t) is 2))
157     )
158
159     $(TR
160     $(TD $(B dchar))
161     $(TD $(B wchar_t) (when sizeof(wchar_t) is 4))
162     )
163
164     $(TR
165     $(TD $(B short))
166     $(TD $(B short))
167     )
168
169     $(TR
170     $(TD $(B ushort))
171     $(TD $(B unsigned short))
172     )
173
174     $(TR
175     $(TD $(B int))
176     $(TD $(B int))
177     )
178
179     $(TR
180     $(TD $(B uint))
181     $(TD $(B unsigned))
182     )
183
184     $(TR
185     $(TD $(B long))
186     $(TD $(B long long))
187     )
188
189     $(TR
190     $(TD $(B ulong))
191     $(TD $(B unsigned long long))
192     )
193
194     $(TR
195     $(TD $(B float))
196     $(TD $(B float))
197     )
198
199     $(TR
200     $(TD $(B double))
201     $(TD $(B double))
202     )
203
204     $(TR
205     $(TD $(B real))
206     $(TD $(B long double))
207     )
208
209     $(TR
210     $(TD $(B ifloat))
211     $(TD $(B float _Imaginary))
212     )
213
214     $(TR
215     $(TD $(B idouble))
216     $(TD $(B double _Imaginary))
217     )
218
219     $(TR
220     $(TD $(B ireal))
221     $(TD $(B long double _Imaginary))
222     )
223
224     $(TR
225     $(TD $(B cfloat))
226     $(TD $(B float _Complex))
227     )
228
229     $(TR
230     $(TD $(B cdouble))
231     $(TD $(B double _Complex))
232     )
233
234     $(TR
235     $(TD $(B creal))
236     $(TD $(B long double _Complex))
237     )
238
239     $(TR
240     $(TD $(B struct))
241     $(TD $(B struct))
242     )
243
244     $(TR
245     $(TD $(B union))
246     $(TD $(B union))
247     )
248
249     $(TR
250     $(TD $(B enum))
251     $(TD $(B enum))
252     )
253
254     $(TR
255     $(TD $(B class))
256     $(TD no equivalent)
257     )
258
259     $(TR
260     $(TD $(I type)$(B *))
261     $(TD $(I type) $(B *))
262     )
263
264     $(TR
265     $(TD $(I type)$(B [)$(I dim)$(B ]))
266     $(TD $(I type)$(B [)$(I dim)$(B ]))
267     )
268
269     $(TR
270     $(TD $(I type)$(B [)$(I dim)$(B ]*))
271     $(TD $(I type)$(B (*)[)$(I dim)$(B ]))
272     )
273
274     $(TR
275     $(TD $(I type)$(B []))
276     $(TD no equivalent)
277     )
278
279     $(TR
280     $(TD $(I type)$(B [)$(I type)$(B ]))
281     $(TD no equivalent)
282     )
283
284     $(TR
285     $(TD $(I type) $(B function)$(B $(LPAREN))$(I parameters)$(B $(RPAREN)))
286     $(TD $(I type)$(B (*))$(B $(LPAREN))$(I parameters)$(B $(RPAREN)))
287     )
288
289     $(TR
290     $(TD $(I type) $(B delegate)$(B $(LPAREN))$(I parameters)$(B $(RPAREN)))
291     $(TD no equivalent)
292     )
293
294     )
295
296     $(P These equivalents hold for most 32 bit C compilers. The C standard
297     does not pin down the sizes of the types, so some care is needed.
298     )
299
300 $(V2
301 <h2>Passing D Array Arguments to C Functions</h2>
302
303     $(P In C, arrays are passed to functions as pointers even if the function
304     prototype says its an array. In D, static arrays are passed by value,
305     not by reference. Thus, the function prototype must be adjusted to match
306     what C expects.)
307
308     $(TABLE1
309     <caption>D And C Function Prototype Equivalence</caption>
310
311     $(TR
312     $(TH D type)
313     $(TH C type)
314     )
315
316     $(TR
317     $(TD $(I T)$(B *))
318     $(TD $(I T)$(B []))
319     )
320
321     $(TR
322     $(TD $(B ref) $(I T)$(B [)$(I dim)$(B ]))
323     $(TD $(I T)$(B [)$(I dim)$(B ]))
324     )
325
326     )
327
328     $(P For example:)
329
330 $(CCODE
331 void foo(int a[3]) { ... } // C code
332 )
333 ---
334 extern (C)
335 {
336   void foo(ref int[3] a); // D prototype
337 }
338 ---
339 )
340
341 <h2>Calling printf()</h2>
342
343     $(P This mostly means checking that the printf format specifier
344     matches the corresponding D data type.
345     Although printf is designed to handle 0 terminated strings,
346     not D dynamic arrays of chars, it turns out that since D
347     dynamic arrays are a length followed by a pointer to the data,
348     the $(TT %.*s) format works perfectly:
349     )
350
351 ------
352 void foo(char[] string)
353 {
354     printf("my string is: %.*s\n", string);
355 }
356 ------
357
358     $(P The $(CODE printf) format string literal
359     in the example doesn't end with $(CODE '\0').
360     This is because string literals,
361     when they are not part of an initializer to a larger data structure,
362     have a $(CODE '\0') character helpfully stored after the end of them.
363     )
364
365     $(P An improved D function for formatted output is
366     $(CODE std.stdio.writef()).
367     )
368
369 <h2>Structs and Unions</h2>
370
371     $(P D structs and unions are analogous to C's.
372     )
373
374     $(P C code often adjusts the alignment and packing of struct members
375     with a command line switch or with various implementation specific
376     #pragma's. D supports explicit alignment attributes that correspond
377     to the C compiler's rules. Check what alignment the C code is using,
378     and explicitly set it for the D struct declaration.
379     )
380
381     $(P D does not support bit fields. If needed, they can be emulated
382     with shift and mask operations.
383     $(LINK2 htod.html, htod) will convert bit fields to inline functions that
384     do the right shift and masks.
385     )
386
387 $(V1
388 <hr>
389 <h1>Interfacing to C++</h1>
390
391     $(P D does not provide an interface to C++, other than
392     through $(LINK2 ../COM.html, COM programming). Since D, however,
393     interfaces directly to C, it can interface directly to
394     C++ code if it is declared as having C linkage.
395     )
396
397     $(P D class objects are incompatible with C++ class objects.
398     )
399 )
400
401 )
402
403 Macros:
404     TITLE=Interfacing to C
405     WIKI=InterfaceToC
Note: See TracBrowser for help on using the browser.