Slide 1

Slide 1 text

Interfacing D With C++ by Walter Bright dlang.org

Slide 2

Slide 2 text

C is the Lingua Franca ● Most every language has some sort of interface with C ● And, of course, the classic being C++ is built on top of C

Slide 3

Slide 3 text

C Interop extern ( C ) { void* malloc(size_t); void free(void*); }

Slide 4

Slide 4 text

C++ Interop?

Slide 5

Slide 5 text

● Name mangling ● Templates ● SFINAE ● Namespaces ● Overloading ● Argument Dependent Lookup

Slide 6

Slide 6 text

Inconceivable! --The Princess Bride

Slide 7

Slide 7 text

● RTTI ● Virtual functions ● Exceptions ● Special member functions ● Operator overloading ● Const Oh My!

Slide 8

Slide 8 text

Imposserous! – The Wizard of Oz

Slide 9

Slide 9 text

You'd have to build a whole C++ front end into the language!

Slide 10

Slide 10 text

Or Maybe Not...

Slide 11

Slide 11 text

Don't have to compile C++, just have to link to it

Slide 12

Slide 12 text

D doesn't have an analog of everything C++ has, so if we can be a bit plastic on both sides...

Slide 13

Slide 13 text

extern (C++) { uint foo(ref char* p); } Should connect to: extern “C++” { unsigned foo(char*& p); }

Slide 14

Slide 14 text

D C++ char char byte signed char ubyte unsigned char short short ushort unsigned short int int uint unsigned long long long ulong unsigned long long

Slide 15

Slide 15 text

What About extern “C++” void foo(long x); (long doesn't seem to have a D analog)

Slide 16

Slide 16 text

struct __c_long { this(int x) { lng = x; } int lng; alias lng this; }

Slide 17

Slide 17 text

Unsolved Const Problem int ****const*** func(); ?func@@YAPAPAPBQAPAPAPAHXZ const(int ****)*** func(); ?func@@YAPAPAPBQBQBQBHXZ

Slide 18

Slide 18 text

Struct Layout Matches C++ C++: struct s { unsigned a; char c; double d; }; D: struct s { uint a; char c; double d; } Static members too!

Slide 19

Slide 19 text

Struct Member Functions The same

Slide 20

Slide 20 text

Polymorphism (virtual functions) ● D classes have virtual functions – But object layout is different – vtbl[] layout is different

Slide 21

Slide 21 text

D Supports COM Interfaces import std.c.windows.com; interface IHello : IUnknown { extern (Windows) int Print(); } class CHello : ComObject, IHello { HRESULT Print() { MessageBoxA(null, “hello”, null, MB_OK); } }

Slide 22

Slide 22 text

Or Simply extern (C++) class C { void func() { … } }

Slide 23

Slide 23 text

Multiple Inheritance Not even once! Lord of the Rings

Slide 24

Slide 24 text

Floor Wax or Dessert Topping? Value or reference type?

Slide 25

Slide 25 text

C++ Namespaces namespace N { namespace M { void foo(); } } namespace N { // not closed void bar(); }

Slide 26

Slide 26 text

D Name Spaces ● module ● struct ● class ● mixin template

Slide 27

Slide 27 text

Extend C++ Declaration extern (C++, N.M) { void foo(); } extern (C++, N) { void bar(); }

Slide 28

Slide 28 text

C++ Templates ● SFINAE ● Partial ordering ● Dependent lookup ● Point of instantiation ● Primary template ● Template templates

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Ignore All That It's just a name mangling problem.

Slide 31

Slide 31 text

C++: template struct Boo { X v[C]; }; D: extern (C++) struct Boo(X, int C) { X[C] v; }

Slide 32

Slide 32 text

Toto Too! C++: template T func(T t) { return t; } func(3); ??$func@H@@YAHH@Z D: extern(C++) T func(T)(T t) { return t; } func(3); ??$func@H@@YAHH@Z Wizard of Oz

Slide 33

Slide 33 text

Now It's Time to Justify My Existence

Slide 34

Slide 34 text

Interface to STL! Let's try and hook up to std::vector

Slide 35

Slide 35 text

std.vector!int p; func(p); calls: void func(std::vector > *p);

Slide 36

Slide 36 text

extern (C++, std) { class vector(T, A = allocator!T) { final void push_back(ref const T); } }

Slide 37

Slide 37 text

extern (C++, std) { struct allocator(T) { alias size_type = size_t; void deallocate(T* p, size_type sz) { (cast(__gnu_cxx.new_allocator!T*)&this).deallocate(p, sz); } } } extern (C++, __gnu_cxx) { struct new_allocator(T) { alias size_type = size_t; void deallocator(T*, size_type); } }

Slide 38

Slide 38 text

Biggest Remaining Problem ● Catching C++ exceptions – which are by value – D exceptions are by reference

Slide 39

Slide 39 text

Tl,Dr; ● Can get pretty far ● Need to be flexible on both ends ● Interfaces to STL are not portable ● and requires non-trivial expertise

Slide 40

Slide 40 text

● It'll never be 100% ● But it's tractable ● And infinitely better than C wrappers ● No longer locked in to existing C++ code