www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 21903] New: Class construction for C++ interop with -betterC

https://issues.dlang.org/show_bug.cgi?id=21903

          Issue ID: 21903
           Summary: Class construction for C++ interop with -betterC
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: zan77137 nifty.com

If you are using betterC and want to interoperate with C++, you may want to
construct instances of your classes in D language code.
In betterC, it should not be possible to use new to do memory allocation in GC,
but it should be possible to use `emplace` to do the construction.

Specifically, I think the following code may work:
-------------------------------------
import core.lifetime: emplace;
import core.stdc.stdio: printf;

extern(C++) class A
{
    int a = 5;
    int foo() { return a; };
}
extern(C++) class B: A
{
    int b = 10;
    override int foo() { return a + b; };
}

extern(C) void main()
{
    ubyte[__traits(classInstanceSize, B)] buf;
    auto b = emplace!B(buf[]);
    printf("%d\n", b.foo());
}
-------------------------------------
dmd -betterC -run main.d
-------------------------------------
https://run.dlang.io/is/QNGYvL

However, this does not work in fact.
This is because `emplace` internally copies memory from typeid(T).initializer
and depends on TypeInfo.

To achieve this, you will need to do one of the following
- Provide a way to get the default initializer value of a member variable. ex)
`__traits(getDefaultInitializerValue, T.a)`
- Make typeid(T).initializer available at compile time. ex) `static immutable
buf = typeid(T).initializer;`
- Provide a way to get a buffer equivalent to typeid(T).initializer. ex)
`static immutable buf = __traits(getInitializerBuffer, T)`

--
May 07 2021