www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - on interfacing w/C++

reply "Ellery Newcomer" <ellery-newcomer utulsa.edu> writes:
(Putting this out there because it sounds like I'm going to get 
scooped in the near future)

So last week I was dinking around with the idea of a library to 
support calling C++ functions. So I wrote some ct code to emulate 
g++ 4.8.2's mangling scheme, and wrote a bit more code to wrap 
it, and calling conventions seemed to work out, and this is what 
I got:

for the C++:

class X {
     public:
         int i;

         X();
         int y();
         void z(int j);

         static int abu(int j);
};

do this:

mixin CppClass!("X",
     typeof(new class {
         int i;
         int y();
         void z(int j);

         static int abu(int j);
     }));
mixin(X.Externs); // waa, issue 12575


it generates something like

struct X {
     int i;
     int y() {
         return _ZN1X1yEv(&this);
     }
     void z(int j) {
         _ZN1X1zEi(&this, j);
     }
     static int abu(int j) {
         return _ZN1X3abuEi(j);
     }
}
extern(C) int _ZN1X1yEv(X*);
extern(C) void _ZN1X1zEi(X*,int);
extern(C) int _ZN1X3abuEi(int);


And it all seems to work. pointer params, reference params, 
variadic params, operators, templates all seem within ready reach.

virtual functions are going to be difficult - I guess you'd have 
to have a complete and accurate list of all fields in the class 
and all its superclasses. And all virtual functions. But g++ 
inserts a vtable symbol for classes with virtual functions - does 
anyone know what the heck that is?

Same for constructing a C++ object from within D - you need a 
valid sizeof.

other compilers won't work as above, the mangling scheme used by 
eg DMC doesn't produce valid D identifiers. Is there a pragma or 
anything to get around this?

And I totally spaced on exceptions until I looked on this forum a 
few minutes ago.

So my plan is to get all these bits implemented, then build a 
tool to validate the C++ and D sides match up, then build a tool 
to generate the D side from C++ headers. And then start expanding 
the list of supported C++ compilers.

Does this sound like a reasonable project? The points of concern 
I am worried about most are:

safety associated with supporting virtual functions
if a c++ mangler is stateful, that would shut me down pretty 
quick.
it requires the C++ compiler/version be specified at a library 
level
exceptions probably won't work
Apr 13 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 14/04/14 00:54, Ellery Newcomer wrote:
 (Putting this out there because it sounds like I'm going to get scooped
 in the near future)

 So last week I was dinking around with the idea of a library to support
 calling C++ functions. So I wrote some ct code to emulate g++ 4.8.2's
 mangling scheme, and wrote a bit more code to wrap it, and calling
 conventions seemed to work out, and this is what I got:
You do know D supports extern(C++)? Although I don't know to which extent. -- /Jacob Carlborg
Apr 14 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Jacob Carlborg"  wrote in message news:lig73r$nvn$1 digitalmars.com...

 You do know D supports extern(C++)? Although I don't know to which extent.
Pretty much everything works except special functions (ctors/dtors/operators).
Apr 14 2014
parent reply Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
Huh? Do methods work now? Since when?
We still have no member function pointers either.


On 15 April 2014 14:25, Daniel Murphy via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 "Jacob Carlborg"  wrote in message news:lig73r$nvn$1 digitalmars.com...


  You do know D supports extern(C++)? Although I don't know to which extent.

 Pretty much everything works except special functions
 (ctors/dtors/operators).
Apr 15 2014
next sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Manu via Digitalmars-d" <digitalmars-d puremagic.com> wrote in message 
news:mailman.9.1397553786.2763.digitalmars-d puremagic.com...

 Huh? Do methods work now? Since when?
Since I needed them for DDMD.
 We still have no member function pointers either.
Meh.
Apr 15 2014
parent reply "Moritz Maxeiner" <moritz ucworks.org> writes:
On Tuesday, 15 April 2014 at 11:04:42 UTC, Daniel Murphy wrote:
 "Manu via Digitalmars-d" <digitalmars-d puremagic.com> wrote in 
 message 
 news:mailman.9.1397553786.2763.digitalmars-d puremagic.com...

 Huh? Do methods work now? Since when?
Since I needed them for DDMD.
Is this[1] then out of date and I can interface with non-virtual methods? Because that's what your post seems to imply (unless I misunderstood). [1] http://dlang.org/cpp_interface.html
Apr 16 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Moritz Maxeiner"  wrote in message 
news:kvzwlecwougswrqkatcs forum.dlang.org...

 Is this[1] then out of date and I can interface with non-virtual methods? 
 Because that's what your post seems to imply (unless I misunderstood).

 [1] http://dlang.org/cpp_interface.html
Yes. The best place to look for concrete examples of what is supported is probably the C++ tests in the test suite. (ie files containing "EXTRA_CPP_SOURCES")
Apr 16 2014
parent reply "Moritz Maxeiner" <moritz ucworks.org> writes:
On Wednesday, 16 April 2014 at 14:00:24 UTC, Daniel Murphy wrote:
 "Moritz Maxeiner"  wrote in message 
 news:kvzwlecwougswrqkatcs forum.dlang.org...

 Is this[1] then out of date and I can interface with 
 non-virtual methods? Because that's what your post seems to 
 imply (unless I misunderstood).

 [1] http://dlang.org/cpp_interface.html
Yes. The best place to look for concrete examples of what is supported is probably the C++ tests in the test suite. (ie files containing "EXTRA_CPP_SOURCES")
That sounds very cool, I've had a look at [1] and [2], which seem to be the two files with the new C++ class interfacing. As far as I could tell, you need to create any instances of C++ classes with C++ code / you don't bind to the constructors directly from D and the new instance will not be managed by D's GC? Because if I used this new interfacing for e.g. llvm-d, I need to be sure, that D's GC won't touch any of the instances under any circumstances, since they are freed by LLVM's internal logic they GC cannot track. [1] https://github.com/D-Programming-Language/dmd/blob/master/test/runnable/externmangle.d [2] https://github.com/D-Programming-Language/dmd/blob/master/test/runnable/extra-files/externmangle.cpp
Apr 16 2014
next sibling parent reply "monnoroch" <monnoroch gmail.com> writes:
What about namespaces?
Apr 16 2014
parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"monnoroch"  wrote in message news:kqjrnqecnfejmiwnkwom forum.dlang.org... 

 What about namespaces?
Zero support currently.
Apr 16 2014
prev sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Moritz Maxeiner"  wrote in message 
news:nadswyordziiiixwaywi forum.dlang.org...

 That sounds very cool, I've had a look at [1] and [2], which seem to be 
 the two files with the new C++ class interfacing. As far as I could tell, 
 you need to create any instances of C++ classes with C++ code / you don't 
 bind to the constructors directly from D and the new instance will not be 
 managed by D's GC? Because if I used this new interfacing for e.g. llvm-d, 
 I need to be sure, that D's GC won't touch any of the instances under any 
 circumstances, since they are freed by LLVM's internal logic they GC 
 cannot track.
This is correct, if you want to construct a class implemented in C++ you will need to call a factory function also implemented in C++, and the same for the other direction. If you are using 'new' in C++ it will not use D's GC heap, unless you overrode the global 'new' operator or something. The simplest model is to do all lifetime management in the original language and ensure that objects stay alive while there are live references in the other language.
Apr 16 2014
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 16 April 2014 at 17:16:07 UTC, Daniel Murphy wrote:
 If you are using 'new' in C++ it will not use D's GC heap, 
 unless you overrode the global 'new' operator or something.
Which, if you did, would enable you to use C++ classes from D somewhat transparently, no?
Apr 16 2014
parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"John Colvin"  wrote in message news:qbwxwxekffpegmbckejx forum.dlang.org...

 Which, if you did, would enable you to use C++ classes from D somewhat 
 transparently, no?
Potentially, yes. You'd need to be very careful that there was always a gc-visible reference to the class to keep it alive, so no using malloc for arrays of class pointers etc in the C++ code. This is done in DDMD by using a wrapper which forwards to GC.malloc.
Apr 16 2014
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/15/14, 2:22 AM, Manu via Digitalmars-d wrote:
 We still have no member function pointers either.
I'd advocate against supporting C++ member function pointers. -- Andrei
Apr 15 2014