You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨C++与C#使用结构体指针时,是否需要手动释放指针?

问题解答

必须手动释放这个Vector2*指针,C#的垃圾回收机制完全无法处理C++堆上分配的内存,不释放会导致内存泄漏。

原因

C中用new分配的内存属于非托管的原生堆,而C#的GC仅负责托管堆(.NET运行时管理的内存)的回收,对非托管内存没有感知。每次调用GetCursorPos都会在C堆上分配8字节(两个float)的内存,不手动释放的话,这些内存会一直占用直到程序退出。

解决方法

方法一:导出释放函数,在C#中调用释放

在C++代码中新增一个用于释放Vector2的导出函数:

extern "C" __declspec(dllexport) void FreeVector2(Vector2* vec)
{
    delete vec;
}

修改C#的调用代码,用finally保证即使出现异常也能释放内存:

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

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

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

方法二:避免动态分配,让C#传入缓冲区(推荐)

这种方式不需要在C中动态分配内存,直接让C#提供结构体实例的指针,C将结果写入其中,从根源上避免内存管理问题:

修改C++的导出函数:

extern "C" __declspec(dllexport) void GetCursorPos(Vector2* outPos)
{
    double xpos, ypos;
    glfwGetCursorPos(Window, &xpos, &ypos);
    outPos->X = (float)xpos;
    outPos->Y = (float)ypos;
}

C#端定义对应结构体并调用:

[StructLayout(LayoutKind.Sequential)]
public struct Vector2
{
    public float X;
    public float Y;
}

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

public static (float x, float y) GetMousePosition()
{
    unsafe
    {
        Vector2 pos;
        GetCursorPos(&pos);
        return (pos.X, pos.Y);
    }
}

内容的提问来源于stack exchange,提问作者bquack-l

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:37:21