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

C++向C#返回enum时出现double free tcache 2错误

问题:C++与C# enum跨语言传递导致退出时double free错误

在Linux .NET6环境下,实现C++与C#之间的enum双向传递时,程序功能正常,但退出时会触发free(): double free detected in tcache 2错误并产生核心转储。经排查:

  • 仅在C向C#返回enum时出现问题,C#向C传递enum无异常
  • 将C++的Test函数改为void返回值后,程序可正常退出
  • 疑惑enum本质是int类型,仅值拷贝无动态内存操作,为何会出现内存错误

相关代码

C++头文件(编译为.so)

enum class Example : int
{
    Item0 = 0,
    Item1 = 1,
    Item2 = 2
};

extern "C" Example Test(Example ex);

C++源文件

#include "header.h"
#include <iostream>

extern "C"
{
    Example Test(Example ex)
    {
        std::cout << "Received enum: " << static_cast<int>(ex) << std::endl;
        return Example::Item2;    // 返回enum会触发问题
    }
}

C#代码(控制台程序)

[DllImport(DLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Test")]
static extern Example Test(Example ex);

Example ex = Test(Example.Item0);
Console.WriteLine("Enum: " + ex.ToString());

enum Example : int
{
    Item0 = 0,
    Item1 = 1,
    Item2 = 2
}

程序输出

$ dotnet test.dll
Received enum: 0
Enum: Item2
free(): double free detected in tcache 2
Aborted (core dumped)

原因分析与解决方案

问题核心是C++强类型枚举enum class的ABI与.NET P/Invoke的处理逻辑不匹配:虽然enum class底层是int,但它属于C++强类型,部分编译器会将其视为非POD(Plain Old Data)类型,返回值通过栈传递;而.NET P/Invoke默认假设返回值是通过寄存器传递的int,这会导致栈内存被错误地重复释放,触发double free。

解决方案1:显式传递int类型

将C++返回值转换为int,C#接收后再转为本地enum:

  • C++修改:
    extern "C" int Test(Example ex)
    {
        std::cout << "Received enum: " << static_cast<int>(ex) << std::endl;
        return static_cast<int>(Example::Item2);
    }
    
  • C#修改:
    [DllImport(DLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Test")]
    static extern int Test(Example ex);
    
    // 调用时转换
    int resultInt = Test(Example.Item0);
    Example ex = (Example)resultInt;
    Console.WriteLine("Enum: " + ex.ToString());
    

解决方案2:改用C风格枚举

去掉C++中的class关键字,使用兼容C的普通枚举,此时编译器会将其视为int兼容的POD类型,P/Invoke可正确处理:

  • C++头文件修改:
    enum Example : int
    {
        Item0 = 0,
        Item1 = 1,
        Item2 = 2
    };
    
    原C#代码无需修改,即可正常运行且无内存错误。

内容的提问来源于stack exchange,提问作者user2205930

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:15:06