Search code examples
c#c++dllimportdllexport

When using pointers to structs and using them between C++ and C#, do I need to delete the pointer?


I have a program which uses C# and C++. C++ is used to do low level things such as rendering. In C# I am making an Input class. It uses GLFW to get the mouse position:

extern "C" __declspec(dllexport) Vector2* GetCursorPos()
{
    double xpos, ypos;
    glfwGetCursorPos(Window, &xpos, &ypos);

    Vector2* pos = new Vector2{ (float)xpos, (float)ypos };
    return pos;
}

Here is the Vector2 struct:

struct Vector2
{
    float X;
    float Y;
};

In the Input class:

[DllImport("Internal.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe Vector2* GetCursorPos();

public static unsafe (float x, float y) GetMousePosition()
{
    Vector2* pos = GetCursorPos();
    return (pos->X, pos->Y);
}

My question is, should I delete this Vector2*, (and where to do so) or is it not needed due to garbage collection in C#.


Solution

  • If using the struct you would have to delete it by creating another function on the c++ side, such as FreeCursorPos

    Alternatively you could just return the x and y pos in the parameters like this:

    In the c++:

    extern "C" __declspec(dllexport) void GetCursorPos(float * outxpos, float * outypos)
    {
        double xpos, ypos;
        glfwGetCursorPos(Window, &xpos, &ypos);
    
        *outxpos = (float)xpos;
        *outypos = (float)ypos;
    }
    

    Not only does this have the advantage that you don't need new and delete, but you no longer need to mark your c# as unsafe

    [DllImport("Internal.dll", CallingConvention = CallingConvention.Cdecl)]
    internal static extern void GetCursorPos(float * outxpos, float * outxpos);
    
    public static (float x, float y) GetMousePosition()
    {
        float outxpos;
        float outxpos;
        GetCursorPos(&outxpos, &outypos);
        return (outxpos, outypos);
    }