Bug 21903 – Class construction for C++ interop with -betterC
Status
RESOLVED
Resolution
WORKSFORME
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-05-07T16:09:17Z
Last change time
2023-04-10T10:08:17Z
Keywords
betterC, C++
Assigned to
No Owner
Creator
SHOO
Comments
Comment #0 by zan77137 — 2021-05-07T16:09:17Z
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)`
Comment #1 by destructionator — 2021-05-07T16:13:34Z
Try
scope B b = new B();
it should work.
Comment #2 by zan77137 — 2021-05-07T16:28:31Z
(In reply to Adam D. Ruppe from comment #1)
> Try
>
> scope B b = new B();
>
> it should work.
This method is not flexible enough for compound use of custom allocators, templates, and classes without default constructors.
Comment #3 by kinke — 2021-11-08T13:53:52Z
This works with LDC v1.27+ due to `__traits(initSymbol, T)` [with an additional `-release` to circumvent a check for matching buffer length requiring druntime].
Comment #4 by razvan.nitu1305 — 2023-04-10T10:08:17Z