Trouble understanding crash when class is returned by value from C++
Andrej Mitrovic
andrej.mitrovich at gmail.com
Mon Sep 3 10:15:54 PDT 2012
On 9/3/12, Iain Buclaw <ibuclaw at ubuntu.com> wrote:
> Indeed, C++ classes are always passed in memory by design. Whereas
pointers could be passed in registers.
That's cool. I learn something new every day. :)
> And this is one
> reason why you need to ensure that function signatures match in both D
> and C/C++ code.
Yeah that's doable when the type is a POD but when it's a class
returned by value there is no equivalent in D since D classes are
always references, so I can't match the D function signature to the C
one.
> extern "C"
> FileName value_FileName(void* refVal)
> {
> return *(FileName*)refVal;
> }
That won't work either since FileName is still in the return type and
I can't match the function signature on the D side (it still crashes).
The only thing I can think of is to match the C++ function signature
to the D side via something like:
C++:
class FileName { ... } // same as before
struct Fake
{
char __thunk[4];
};
Fake value_FileName(void* refVal)
{
return *(Fake*)(&(*(FileName*)refVal));
}
It's ugly but it does seem to work and matches the D function
signature. It would be a lot simpler if the return type was castable
to (char[4]), but C/++ doesn't support returning arrays by value. :)
> By the way, why extern "C" when extern (C++) works just fine? :-)
I'm working on a codegenerator which uses C as the glue language,
similar to SWIG. But the plan is to support more features than SWIG
and have a faster and less memory-intensive cross-language virtual
method invocation mechanism. Unlike SWIG I support passing PODs by
value, but passing non-POD classes by value was problematic and I can
see now why.
Thanks for your help guys!
More information about the D.gnu
mailing list