Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve friendliness of constructing/destructing C++ objects #161

Open
PathogenDavid opened this issue Feb 21, 2021 · 1 comment
Open

Improve friendliness of constructing/destructing C++ objects #161

PathogenDavid opened this issue Feb 21, 2021 · 1 comment
Labels
Concept-OutputFriendliness Issues concerning the friendliness of using the Biohazrd output

Comments

@PathogenDavid
Copy link
Member

Right now Biohazrd emits constructors and destructors as normal instance methods, they both act as if they would for placement new.

This leads to somewhat clunky usage for allocating objects from C#. For example:

struct MyStruct
{
public:
    float x;
    float y;
    MyClass(float x, float y);
    ~MyClass();
};

Will generate something like:

[StructLayout(LayoutKind.Explicit, Size = 8)]
public unsafe partial struct MyStruct
{
    [FieldOffset(0)] public float x;
    [FieldOffset(4)] public float y;

    [DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "__InlineHelper0", ExactSpelling = true)]
    private static extern void Constructor_PInvoke(MyStruct* @this, float x, float y);

    [DebuggerStepThrough, DebuggerHidden]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public unsafe void Constructor(float x, float y)
    {
        fixed (ImVec2* @this = &this)
        { Constructor_PInvoke(@this, x, y); }
    }

    [DllImport("InfectedImGui.Native.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "__InlineHelper1", ExactSpelling = true)]
    private static extern void Destructor_PInvoke(MyStruct* @this);

    [DebuggerStepThrough, DebuggerHidden]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public unsafe void Destructor()
    {
        fixed (MyStruct* @this = &this)
        { Destructor_PInvoke(@this); }
    }
}

"Proper" usage of this type in a stack-allocated context looks like this:

MyStruct myStruct = default;
myStruct.Constructor(100f, 200f);
Console.WriteLine($"myStruct = {myStruct.x}, {myStruct.y}");
myStruct.Destructor();

Ideally we'd like it to be able to look like this:

using (MyStruct myStruct = new(100f, 200f))
{ Console.WriteLine($"myStruct = {myStruct.x}, {myStruct.y}"); }

Other things we should ideally support:

Other things to ponder:

  • Should constructors be exposed as static methods instead? (Would allow placement new more naturally, struct constructors would be wrappers of it.)
@PathogenDavid PathogenDavid added the Concept-OutputFriendliness Issues concerning the friendliness of using the Biohazrd output label Feb 21, 2021
@PathogenDavid
Copy link
Member Author

It's somehow not mentioned above, but parameterless constructors are coming to C# 10 so that solves the main reason I hadn't actually done this yet. Julien Couvreur confirmed they should land in 2022p3: dotnet/roslyn#54359 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Concept-OutputFriendliness Issues concerning the friendliness of using the Biohazrd output
Projects
None yet
Development

No branches or pull requests

1 participant