On Wednesday, 9 August 2017 at 18:43:27 UTC, Walter Bright wrote:
On 8/8/2017 2:04 PM, Jacob Carlborg wrote:

[snip]
Of course, there's always pragma(mangle) as well.

Yes these work:
```
    pragma(mangle, convertMangleToCppRef(g.mangleof))
    void g(Klass);

    pragma(mangle, mangleAsCpp("void Klass::g(Klass&)")
    void g(Klass);
```
`convertMangleToCppRef` and `mangleAsCpp` are not going to be easy to implement, but perhaps it can be made to work relatively easily for common cases. (hardcoded mangling won't work in a template class)
Any takers for a dub package? ;-)

On Wednesday, 9 August 2017 at 18:43:27 UTC, Walter Bright wrote:

As Jacob hints at, the C++ name mangling for Klass* and Klass& is different. D classes are implicitly by reference. So which mangling to choose? D chose the Klass*.

Let's keep this discussion focussed on solutions. We all know what the cause of the problem is.

The best way to deal with that is, on the C++ side, add:

    void foo(Klass* k) { foo(*k); }

If this is the accepted solution (i.e. don't improve status quo), it means the only way to bind to common C++ libs is to set up a C++ build step for your project. This is already needed for instantiating templated C++ code, so perhaps it's not so bad, but definitely painful if things would have worked easily if only one could annotate things to slightly adjust the C++mangling. Also, automatically generating the trampolines will be a "fun" challenge for a binding tool writer.
By the way, UFCS does help nicely for class method trampolines.

```
// C++
class B {};
class A {
    void foo(B&);
};

// in C++ bindings file
void foo(A* a, B* b) { a->foo(*b); }
```

```
// D bindings file
extern (C++) class A {}
extern (C++) class B {}
extern (C++) void foo(A a, B b);

// D user code
void g(A a, B b) {
    a.foo(b);
}
```

I think this is important information to provide clarity on in the "Interfacing to C++" documentation.

-Johan

Reply via email to