digitalmars.D - extern(C++) template problem
- Manu (16/17) May 23 2018 C++:
- Nicholas Wilson (10/32) May 23 2018 or
- Manu (10/50) May 23 2018 Sadly, neither of these are correct.
- Walter Bright (13/21) May 25 2018 One way is to create a wrapper for C in another module:
- Manu (6/28) May 25 2018 Ah, interesting strategy!
C++: --------------------------------------- class C {}; template <typename T> void create(T** x); --------------------------------------- D: --------------------------------------- extern(C++) class C {} void create(T)(T* x); --------------------------------------- Trouble is; in CPP, the template mangles as a C, but in D, the class mangles as C*... so the mangling doesn't match. `template<typename Class>` is an unbelievably common occurrence in C++... but how do we express a signature that mangles correctly in D? D always mangles `Class` as `Class*`... which changes the signature._<
May 23 2018
On Wednesday, 23 May 2018 at 07:09:40 UTC, Manu wrote:C++: --------------------------------------- class C {}; template <typename T> void create(T** x); --------------------------------------- D: --------------------------------------- extern(C++) class C {} void create(T)(T* x); --------------------------------------- Trouble is; in CPP, the template mangles as a C, but in D, the class mangles as C*... so the mangling doesn't match. `template<typename Class>` is an unbelievably common occurrence in C++... but how do we express a signature that mangles correctly in D? D always mangles `Class` as `Class*`... which changes the signature.I believe you are looking for_<extern(C++,class) struct C {} void create(T)(T** x);orextern(C++,struct) class C {} void create(T)(T** x);I can't remember which is the one you want here (still half asleep from jet lag). in the case of e.g. extern(C++,struct) class C {} this tells the D compiler that is should mangle it as though it is a struct (as it is declared in C++ as a struct) but it actually has a vtable and behaves like a class from the D school of thought. Vice versa for extern(C++,class) struct C {}
May 23 2018
On 23 May 2018 at 03:14, Nicholas Wilson via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Wednesday, 23 May 2018 at 07:09:40 UTC, Manu wrote:Sadly, neither of these are correct. The type is a class (has vtable, etc), so it is declared in D as a class... It is also a class in C++, so it must mangle like a class. It's also the case that it's passed by pointer, in C++ and in D. It's a class that definitely behaves like a class. The trouble is getting the class name into the function signature as T, where the D compiler really wants to put Class* because that's the type it sees a D class to be.C++: --------------------------------------- class C {}; template <typename T> void create(T** x); --------------------------------------- D: --------------------------------------- extern(C++) class C {} void create(T)(T* x); --------------------------------------- Trouble is; in CPP, the template mangles as a C, but in D, the class mangles as C*... so the mangling doesn't match. `template<typename Class>` is an unbelievably common occurrence in C++... but how do we express a signature that mangles correctly in D? D always mangles `Class` as `Class*`... which changes the signature.I believe you are looking for_<extern(C++,class) struct C {} void create(T)(T** x);orextern(C++,struct) class C {} void create(T)(T** x);I can't remember which is the one you want here (still half asleep from jet lag). in the case of e.g. extern(C++,struct) class C {} this tells the D compiler that is should mangle it as though it is a struct (as it is declared in C++ as a struct) but it actually has a vtable and behaves like a class from the D school of thought. Vice versa for extern(C++,class) struct C {}
May 23 2018
On 5/23/2018 10:48 AM, Manu wrote:Sadly, neither of these are correct. The type is a class (has vtable, etc), so it is declared in D as a class... It is also a class in C++, so it must mangle like a class. It's also the case that it's passed by pointer, in C++ and in D. It's a class that definitely behaves like a class. The trouble is getting the class name into the function signature as T, where the D compiler really wants to put Class* because that's the type it sees a D class to be.One way is to create a wrapper for C in another module: ---- a.d ----- extern (C++) class C { ... } ---- b.d ----- import a; extern (C++) struct C { a.C m; alias m this; } -------------- This relies on D regarding a.C and b.C as different symbols, even though they mangle the same.
May 25 2018
On 25 May 2018 at 11:28, Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 5/23/2018 10:48 AM, Manu wrote:Ah, interesting strategy! Although, they don't mangle the same... extern (C++, class) struct C { ... } That should do it! :)Sadly, neither of these are correct. The type is a class (has vtable, etc), so it is declared in D as a class... It is also a class in C++, so it must mangle like a class. It's also the case that it's passed by pointer, in C++ and in D. It's a class that definitely behaves like a class. The trouble is getting the class name into the function signature as T, where the D compiler really wants to put Class* because that's the type it sees a D class to be.One way is to create a wrapper for C in another module: ---- a.d ----- extern (C++) class C { ... } ---- b.d ----- import a; extern (C++) struct C { a.C m; alias m this; } -------------- This relies on D regarding a.C and b.C as different symbols, even though they mangle the same.
May 25 2018