digitalmars.D.learn - Small structs: interfacing with C++ potentially broken
- Jan (42/42) Dec 20 2021 I have a small struct that I'm trying to interface to.
I have a small struct that I'm trying to interface to. C++ ```cpp struct __declspec(dllexport) SmallStruct { float value = 0; //float value2 = 0; //float value3 = 0; SmallStruct(float val) : value(val) { } static SmallStruct GetValue(float input) { return SmallStruct(input * 3.141f); } }; ``` And on the D side: ```cpp extern(C++) struct SmallStruct { float value = 0; // float value2 = 0; // float value3 = 0; static SmallStruct GetValue(float input); }; ``` Then I use it like this: ```cpp SmallStruct s = SmallStruct.GetValue(3); ``` Running this crashes on the C++ side, with an access violation writing data. Looking at the disassembly, it seems that C++ expects the Smallstruct return object to be passed in, whereas D assumes that the SmallStruct is passed through registers. This is with MVSC 2019 compiled for x64 and DMD v2.098.0. If I enable 'value2' and 'value3', it seems that both compilers start to agree on the calling convention. Is this a known issue, or is there a way to instruct DMD to use a specific calling convention for a given type?
Dec 20 2021
On Monday, 20 December 2021 at 10:24:00 UTC, Jan wrote:Is this a known issue, or is there a way to instruct DMD to use a specific calling convention for a given type?This looks like a bug. It seems to work without constructor in C++, but still crashes with a constructor in D. It also seems to work if a trivial destructor is added in D: ~this(){} This could be related to POD types in C++. Structs with constructor or destructor are probably passed differently, but dmd only looks at the destructor.
Dec 20 2021
On Monday, 20 December 2021 at 11:58:03 UTC, Tim wrote:On Monday, 20 December 2021 at 10:24:00 UTC, Jan wrote:I think it's got something to do with [this](https://forum.dlang.org/post/capevemlbdanirtcjwfk forum.dlang.org)Is this a known issue, or is there a way to instruct DMD to use a specific calling convention for a given type?This looks like a bug. It seems to work without constructor in C++, but still crashes with a constructor in D. It also seems to work if a trivial destructor is added in D: ~this(){} This could be related to POD types in C++. Structs with constructor or destructor are probably passed differently, but dmd only looks at the destructor.
Dec 20 2021
On Monday, 20 December 2021 at 11:58:03 UTC, Tim wrote:On Monday, 20 December 2021 at 10:24:00 UTC, Jan wrote:Well, that at least gives me a way to work around this issue.Is this a known issue, or is there a way to instruct DMD to use a specific calling convention for a given type?This looks like a bug. It seems to work without constructor in C++, but still crashes with a constructor in D. It also seems to work if a trivial destructor is added in D: ~this(){} This could be related to POD types in C++. Structs with constructor or destructor are probably passed differently, but dmd only looks at the destructor.
Dec 20 2021