Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 18, 2013 C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
At the current time D have powerful mechanism of access to C++ classes. For access to methods of C++ classes (virtual and not) we can use extern(C++) interface. //С++ class CPPTest1 { int a; int b; public: virtual int boom(); int fun(); static int gun(); CPPTest1(int); virtual ~CPPTest1(); int& operator[](size_t); }; class CPPTest2: public CPPTest1 { int boom(); }; //D extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); } extern(C++)interface CPPTest2: CPPTest1 { //int boom(); } As a rule, non-static fields are not public in C++ classes and is not part of interface. Thus the most of C++ classes can be bound without any glue c++ code. However D dont support C++ overloaded operators and constructors. Yes, we cannot make mapping C++ operators to D operators and C++ constructors to D constructors). Nonetheless С++ operators and constructors are the simple C++ functions or methods with special mangling. Thus I've suggest next mechanism: Allow special pragma(cppSymbol, string_arg), when string_arg is the name of c++ thing. Example: extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); ///!!!! pragma(cppSymbol, "constructor") final void ctor(int); //linked with CPPTest1(int); pragma(cppSymbol, "destructor") void dtor(); //linked with virtual ~CPPTest1(); pragma(cppSymbol, "[]") ref int indexOf(size_t); //linked with int& operator[](size_t); } This pragma must apply to the function (or method), use natural C++ mangle, but set operatror or constructor or destructor mangled name instead of function name. Is it useful idea? |
May 18, 2013 Re: C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Igor Stepanov | On 05/18/2013 03:23 PM, Igor Stepanov wrote: > natural C++ mangle That's part of the problem: C++ name mangling is not standardized. Ali |
May 18, 2013 Re: C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Saturday, 18 May 2013 at 22:55:34 UTC, Ali Çehreli wrote:
> On 05/18/2013 03:23 PM, Igor Stepanov wrote:
>
> > natural C++ mangle
>
> That's part of the problem: C++ name mangling is not standardized.
>
> Ali
But D compilers are using C++ mangle for extern(C++) functions now.
I think, this trouble can be solved in a glue layer of compiler. Now, on posix we can use gcc c++ mangle, on windows - dmc/visual c++ mangle.
As I know, there is not many kinds of c++ mangle. over 10:)
Current implementation use only two: dmc for windows, gcc for posix. If another back-end will be added, we can add another mangle support.
I think, C++ to D binding is a very important issue. If D will provide good mechanism of binding, some projects will can be simple moved to D and some project leaders will can choose D to develop his projects.
|
May 18, 2013 Re: C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Igor Stepanov Attachments:
| On May 18, 2013 11:25 PM, "Igor Stepanov" <wazar.leollone@yahoo.com> wrote: > > At the current time D have powerful mechanism of access to C++ classes. For access to methods of C++ classes (virtual and not) we can use extern(C++) interface. > > //С++ > > class CPPTest1 > { > int a; > int b; > public: > virtual int boom(); > int fun(); > static int gun(); > CPPTest1(int); > virtual ~CPPTest1(); > int& operator[](size_t); > }; > > class CPPTest2: public CPPTest1 > { > int boom(); > }; > > //D > extern(C++)interface CPPTest1 > { > int boom(); > static int gun(); > final int fun(); > } > > extern(C++)interface CPPTest2: CPPTest1 > { > //int boom(); > } > > > > As a rule, non-static fields are not public in C++ classes and is not part of interface. Thus the most of C++ classes can be bound without any glue c++ code. > However D dont support C++ overloaded operators and constructors. Yes, we cannot make mapping C++ operators to D operators and C++ constructors to D constructors). Nonetheless С++ operators and constructors are the simple C++ functions or methods with special mangling. Thus I've suggest next mechanism: > Allow special pragma(cppSymbol, string_arg), when string_arg is the name of c++ thing. > Example: > > extern(C++)interface CPPTest1 > { > int boom(); > static int gun(); > final int fun(); > ///!!!! > pragma(cppSymbol, "constructor") final void ctor(int); //linked with CPPTest1(int); > pragma(cppSymbol, "destructor") void dtor(); //linked with virtual ~CPPTest1(); > pragma(cppSymbol, "[]") ref int indexOf(size_t); //linked with int& operator[](size_t); > } > > This pragma must apply to the function (or method), use natural C++ mangle, but set operatror or constructor or destructor mangled name instead of function name. > > Is it useful idea? No. Regards -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; |
May 19, 2013 Re: C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | >No.
Ok. As I know, there is running process to moving DMD front-end from C++ to D. As I remember, process expect to be gradual. Thus I the same moment will be C++ classes and D classes in the frontend. How you are planning create new C++ objects from D? Are you planning add to all classes special "constructor" static method, which will create new instances of C++ classes and return it, or you see another way to do it?
|
May 19, 2013 Re: C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Igor Stepanov Attachments:
| On 19 May 2013 13:20, Igor Stepanov <wazar.leollone@yahoo.com> wrote: > No. >> > Ok. As I know, there is running process to moving DMD front-end from C++ to D. As I remember, process expect to be gradual. Thus I the same moment will be C++ classes and D classes in the frontend. How you are planning create new C++ objects from D? Are you planning add to all classes special "constructor" static method, which will create new instances of C++ classes and return it, or you see another way to do it? > > All new'ing will be done in D. The C++ glue-layer methods are a problem, and we will be moving to using a visitor interface between the two. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; |
May 19, 2013 Re: C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | Is this mean, that D functions will _not_ create C++ objects with new? For example: You have moved parser to D, but you haven't moved expressions to D yet. And you want to create new Expression object in parser (in D code), but Expression class defined in C++. What will you do in this case? |
May 19, 2013 Re: C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Igor Stepanov | "Igor Stepanov" <wazar.leollone@yahoo.com> wrote in message news:wuevxraaffhaaceapqfv@forum.dlang.org... > Is this mean, that D functions will _not_ create C++ objects with new? > For example: > You have moved parser to D, but you haven't moved expressions to D yet. > And you want to create new Expression object in parser (in D code), but > Expression class defined in C++. What will you do in this case? This is not how we're moving it. The entire frontend will be moved in one go, there will never be a need to create a C++ class from D. That said, the glue layer will remain in C++ and will need to create instances of classes defined in D. The current glue layer calls 43 different constructors. I don't have a solution for this yet, but it will probably be: a) Extend D to allow creating classes with constructors callable from C++ b) Create/generate factory functions for each class new'd in the glue layer c) Remove all class allocations from the glue layer I'm leaning towards b, or maybe c, and I think you should too. |
May 19, 2013 Re: C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Murphy | On Sunday, 19 May 2013 at 13:56:56 UTC, Daniel Murphy wrote:
> "Igor Stepanov" <wazar.leollone@yahoo.com> wrote in message
> news:wuevxraaffhaaceapqfv@forum.dlang.org...
>> Is this mean, that D functions will _not_ create C++ objects with new?
>> For example:
>> You have moved parser to D, but you haven't moved expressions to D yet.
>> And you want to create new Expression object in parser (in D code), but Expression class defined in C++. What will you do in this case?
>
> This is not how we're moving it. The entire frontend will be moved in one
> go, there will never be a need to create a C++ class from D.
>
> That said, the glue layer will remain in C++ and will need to create
> instances of classes defined in D. The current glue layer calls 43
> different constructors.
>
> I don't have a solution for this yet, but it will probably be:
> a) Extend D to allow creating classes with constructors callable from C++
> b) Create/generate factory functions for each class new'd in the glue layer
> c) Remove all class allocations from the glue layer
>
> I'm leaning towards b, or maybe c, and I think you should too.
Yes, language shouldn't be modified for the sake of one goal.
But do you think, that calling C++ constructors from D is not typical task? I sure, that we must get a common way to bind C++ classes to D. No templates, no exceptions. But operators and constructors/destructors is needed. It may be special tool, that eat C++ header and return D file + C++ glue file. This util should transform all fields and constructors to D final methods for extern(C++) interface.
In addition to this tool we can make a D binding layer, which simplify typical operations such as creating C++ objects using ::operator new() (or class operator new() if in exists) and destroying with operator delete() (local or global).
By the way: Why D disallow static __gshared C++ variables in classes? This is a principled feature (if yes: why?) or omission?
|
May 20, 2013 Re: C++ constructors, destructors and operator access | ||||
---|---|---|---|---|
| ||||
Posted in reply to Igor Stepanov | On Saturday, 18 May 2013 at 22:23:51 UTC, Igor Stepanov wrote:
> At the current time D have powerful mechanism of access to C++ classes.
> For access to methods of C++ classes (virtual and not) we can use extern(C++) interface.
>
> //С++
>
> class CPPTest1
> {
> int a;
> int b;
> public:
> virtual int boom();
> int fun();
> static int gun();
> CPPTest1(int);
> virtual ~CPPTest1();
> int& operator[](size_t);
> };
>
> class CPPTest2: public CPPTest1
> {
> int boom();
> };
>
> //D
> extern(C++)interface CPPTest1
> {
> int boom();
> static int gun();
> final int fun();
> }
>
> extern(C++)interface CPPTest2: CPPTest1
> {
> //int boom();
> }
>
>
>
> As a rule, non-static fields are not public in C++ classes and is not part of interface. Thus the most of C++ classes can be bound without any glue c++ code.
> However D dont support C++ overloaded operators and constructors. Yes, we cannot make mapping C++ operators to D operators and C++ constructors to D constructors). Nonetheless С++ operators and constructors are the simple C++ functions or methods with special mangling. Thus I've suggest next mechanism:
> Allow special pragma(cppSymbol, string_arg), when string_arg is the name of c++ thing.
> Example:
>
> extern(C++)interface CPPTest1
> {
> int boom();
> static int gun();
> final int fun();
> ///!!!!
> pragma(cppSymbol, "constructor") final void ctor(int); //linked with CPPTest1(int);
> pragma(cppSymbol, "destructor") void dtor(); //linked with virtual ~CPPTest1();
> pragma(cppSymbol, "[]") ref int indexOf(size_t); //linked with int& operator[](size_t);
> }
>
> This pragma must apply to the function (or method), use natural C++ mangle, but set operatror or constructor or destructor mangled name instead of function name.
>
> Is it useful idea?
you can do this yourself just with mixins and templates, but the real problem is c++ abi and name mangling. so you will need to do runtime search for c++ mangled names and which runtime used, get it and call placement new and ctor(with the help of asm{} of course), do the same for other operators. it is possible, but this is never be safe at least due to non-standardized name mangling.
you can write small library which would help doing this all if you really want this.
|
Copyright © 1999-2021 by the D Language Foundation