Differences

This shows you the differences between two versions of the page.

Link to this comparison view

dss:laboratoare:07 [2019/07/03 15:16]
razvan.nitu1305
dss:laboratoare:07 [2021/07/19 10:08] (current)
razvan.nitu1305 [Vibe.d]
Line 94: Line 94:
  
 For popular C libraries, the first place to look for the corresponding D interface file is the [[https://​github.com/​D-Programming-Deimos/​|Deimos Project]]. If it isn't there already, and you write one, please contribute it to the Deimos Project. For popular C libraries, the first place to look for the corresponding D interface file is the [[https://​github.com/​D-Programming-Deimos/​|Deimos Project]]. If it isn't there already, and you write one, please contribute it to the Deimos Project.
 +
 +=== Accessing C globals ===
 +
 +C globals can be accessed directly from D. C globals have the C naming convention, and so must be in an **extern (C)** block. Use the **extern** storage class to indicate that the global is allocated in the C code, not the D code. C globals default to being in global, not thread local, storage. To reference global storage from D, use the **gshared** storage class.
 +
 +<code D>
 +extern (C) __gshared int x;
 +</​code>​
 +
 +==== Interfacing to C++ ====
 +
 +Calling D functions from C++ and viceversa are achieved exactly the same as in the case of C, by using **extern(C++)**.
 +
 +=== C++ namespaces ===
 +
 +C++ symbols that reside in namespaces can be accessed from D. A namespace can be added to the **extern (C++)** linkage attribute:
 +
 +<code D>
 +extern (C++, N) int foo(int i, int j, int k);
 +
 +void main()
 +{
 +    N.foo(1, 2, 3);   // foo is in C++ namespace '​N'​
 +}
 +</​code>​
 +
 +=== Classes ===
 +
 +C++ classes can be declared in D by using the **extern (C++)** attribute on class, struct and interface declarations. **extern (C++)** interfaces have the same restrictions as D interfaces, which means that Multiple Inheritance is supported to the extent that only one base class can have member fields.
 +
 +**extern (C++)** structs do not support virtual functions but can be used to map C++ value types.
 +
 +Unlike classes and interfaces with D linkage, **extern (C++)** classes and interfaces are not rooted in **Object** and cannot be used with **typeid**.
 +
 +=== Structs ===
 +
 +C++ allows a struct to inherit from a base struct. This is done in D using alias this.
 +
 +=== C++ Templates ===
 +
 +C++ function and type templates can be bound by using the **extern (C++)** attribute on a function or type template declaration.
 +
 +Note that all instantiations used in D code must be provided by linking to C++ object code or shared libraries containing the instantiations.
 +
 +==== BetterC ====
 +
 +It is straightforward to link C functions and libraries into D programs. But linking D functions and libraries into C programs is not straightforward.
 +
 +D programs generally require:
 +
 +  - The D runtime library to be linked in, because many features of the core language require runtime library support.
 +  - The **main()** function to be written in D, to ensure that the required runtime library support is properly initialized.
 +
 +To link D functions and libraries into C programs, it's necessary to only require the C runtime library to be linked in. This is accomplished by defining a subset of D that fits this requirement,​ called BetterC. BetterC is typically enabled by setting the -betterC command line flag for the implementation.
 +
 +D features not available with BetterC:
 +
 +  * Garbage Collection
 +  * TypeInfo and ModuleInfo
 +  * Classes
 +  * Built-in threading (e.g. core.thread)
 +  * Dynamic arrays (though slices of static arrays work) and associative arrays
 +  * Exceptions
 +  * synchronized and core.sync
 +  * Static module constructors or destructors
 +  * Vector Extensions
 +
 +==== Dub ====
 +
 +Dub is a package and build manager for D applications and libraries.
 +
 +For a dub tutorial, visit this [[https://​dub.pm/​|page]].
 +
 +==== DPP ====
 +
 +D was designed from the beginning to be ABI compatible with C. Translate the declarations from a C header file into a D module and you can link directly with the corresponding C library or object files. The same is true in the other direction as long as the functions in the D code are annotated with the appropriate linkage attribute. These days, it’s possible to bind with C++ and even Objective-C.
 +
 +dpp is a compiler wrapper that will parse a D source file with the .dpp extension and expand in place any #include directives it encounters, translating all of the C or C++ symbols to D, and then pass the result to a D compiler (DMD by default). Example:
 +
 +<code D>
 +// stdlib.dpp
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +
 +void main() {
 +    printf("​Hello world\n"​.ptr);​
 +
 +    enum numInts = 4;
 +    auto ints = cast(int*) malloc(int.sizeof * numInts);
 +    scope(exit) free(ints);
 +
 +    foreach(int i; 0 .. numInts) {
 +        ints[i] = i;
 +        printf("​ints[%d]:​ %d ".ptr, i, ints[i]);
 +    }
 +
 +    printf("​\n"​.ptr);​
 +}
 +</​code>​
 +
 +
 +
 +===== Exercises ====
 +
 +==== 1. C function interface ====
 +
 +  - Write a D function that computes the average of an array of ints.
 +  - Write a main function in C that calls the function previously defined.
 +  - Compile the code. Does it work? Why?
 +
 +<note hint>
 +How are arrays represented in D? But in C?
 +</​note>​
 +
 +==== 2. C struct interface ====
 +
 +  - Write a C function, called **sumMembers** that receives a parameter of type **struct List3** that packs 3 integer values and computes the sum of the 3 members. Define struct Node and a main function that calls **sumMembers**.
 +  - Reimplement **sumMembers** in D by cut-pasting the original code. When linking the objects try using both **gcc** and **dmd**. What happens?
 +  - Redesign **sumMembers** by initializing a builtin array from the members and calling the library function [[https://​dlang.org/​phobos/​std_algorithm_iteration.html#​sum|sum]] on it. Before calling sum, manually add 5 and 6 to the array by using the concatenation equals operator "​~="​. When linking, try using both **gcc** and **dmd**. What happens? Why? 
 +  - Compile the D code with betterC. What happens? Why?
 +
 +==== 3. Dub ====
 +
 +Clone [[https://​github.com/​libmir/​mir|this repo]]. That is a competing library of phobos. Build, run and test the program using dub.
 +
 +==== 4. DPP ====
 +
 +Install dpp by using dub:
 +
 +<code bash>
 +sudo apt-get install libclang1-3.9 libclang-3.9-dev
 +dub fetch libclang
 +dub build libclang
 +dub fetch dpp
 +dub build dpp
 +</​code>​
 +
 +dpp will be installed in **~/​.dub/​packages/​dpp-some-version**. You should probably create an alias with the executable.
 +
 +Write a D program of your choosing in which you use C-style **include** directives. Compile and run the program with dpp.
dss/laboratoare/07.1562156219.txt.gz · Last modified: 2019/07/03 15:16 by razvan.nitu1305
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0