Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Interfacing D To Legacy C++ Code

Interfacing D To Legacy C++ Code

Abstract
C++ programmers have developed a vast investment of existing code. Use of this code from
other languages is normally impractical. Walter shows how
this code can be accessible from the D programming language.

C is the lingua franca of the programming language industry. By presenting a C interface, most languages can connect with one another, and connect to a vast treasure house of C code. But C++ code is very hard to provide an interface too, and almost no languages even attempt it. I'd long ago decided that in order to provide a direct interface from D to C++ would require essentially adding the full semantics of a C++ compiler to D, and that would be impractical. But the idea persistently recurs, as there is a lot of interest in interfacing D to legacy C++ code.

It turns out that we actually can, with minor adjustments to D, directly interface to quite a bit of C++, especially if one is willing to be a bit flexible on both the C++ and D sides. This presentation goes through the principles on how this works, what works and what doesn't work, and how one can retain an investment in C++ code while migrating to D.

Bio
Walter Bright is the creator and first implementer of the D programming language and has implemented compilers for several other languages. He's an expert in all areas of compiler technology, including front ends, optimizers, code generation, interpreter engines and runtime libraries. Walter regularly writes articles about compilers and programming, is known for engaging and informative presentations, and provides training in compiler development techniques. Many are surprised to discover that Walter is also the creator of the wargame Empire, which is still popular today over 30 years after its debut.

Northwest C++ Users' Group

January 21, 2015
Tweet

More Decks by Northwest C++ Users' Group

Other Decks in Programming

Transcript

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

    View full-size slide

  2. 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

    View full-size slide

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

    View full-size slide

  4. C++ Interop?

    View full-size slide


  5. Name mangling

    Templates

    SFINAE

    Namespaces

    Overloading

    Argument Dependent Lookup

    View full-size slide

  6. Inconceivable!
    --The Princess Bride

    View full-size slide


  7. RTTI

    Virtual functions

    Exceptions

    Special member functions

    Operator overloading

    Const
    Oh My!

    View full-size slide

  8. Imposserous!
    – The Wizard of Oz

    View full-size slide

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

    View full-size slide

  10. Or Maybe Not...

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  14. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  18. 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!

    View full-size slide

  19. Struct Member Functions
    The same

    View full-size slide

  20. Polymorphism (virtual functions)

    D classes have virtual functions
    – But object layout is different
    – vtbl[] layout is different

    View full-size slide

  21. 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);
    }
    }

    View full-size slide

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

    View full-size slide

  23. Multiple Inheritance
    Not even once!
    Lord of the Rings

    View full-size slide

  24. Floor Wax or Dessert Topping?
    Value or reference type?

    View full-size slide

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

    View full-size slide

  26. D Name Spaces

    module

    struct

    class

    mixin template

    View full-size slide

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

    View full-size slide

  28. C++ Templates

    SFINAE

    Partial ordering

    Dependent lookup

    Point of instantiation

    Primary template

    Template templates

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  31. 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

    View full-size slide

  32. Now It's Time to Justify My
    Existence

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  36. 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);
    }
    }

    View full-size slide

  37. Biggest Remaining Problem

    Catching C++ exceptions
    – which are by value
    – D exceptions are by reference

    View full-size slide

  38. Tl,Dr;

    Can get pretty far

    Need to be flexible on both ends

    Interfaces to STL are not portable

    and requires non-trivial expertise

    View full-size slide


  39. It'll never be 100%

    But it's tractable

    And infinitely better than C wrappers

    No longer locked in to existing C++ code

    View full-size slide