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

如何从C#向C++ DLL传递数组末尾的指针引用?

解决C#调用ryg_rans时传递数组末尾指针的问题

1. 修正DllImport函数封装

你的C#封装中第二个参数类型错误:C++函数的uint32_t** pptr是指针的指针,用于在函数内部修改指针本身的值(让指针向前移动),而你当前用的ref uint是值类型的引用,完全不匹配。需要将参数类型改为ref IntPtr,因为IntPtr是C#中用于表示非托管内存指针的类型:

[DllImport(DllPath, EntryPoint = "Rans64EncPutSymbol")]
public static extern void Rans64EncPutSymbol(
    ref Rans64State r, 
    ref IntPtr pptr, 
    ref Rans64EncSymbol sym, 
    uint scaleBits = DEFAULT_SCALE_BITS);

// 同步修正Rans64EncFlush的封装(若之前定义有误)
[DllImport(DllPath, EntryPoint = "Rans64EncFlush")]
public static extern void Rans64EncFlush(ref Rans64State r, ref IntPtr pptr);

2. 正确处理托管数组与指针传递

C#的托管数组会被GC自动管理,直接传递数组元素的引用无法满足需求,必须固定数组内存并获取其非托管指针,再计算出数组末尾的指针:

uint[] outputBuffer = new uint[OUT_MAX_ELEMS];
Rans64State ransState = new Rans64State();
RansWrapper.Rans64EncInit(ref ransState);

// 固定托管数组,防止GC移动或回收它
GCHandle bufferHandle = GCHandle.Alloc(outputBuffer, GCHandleType.Pinned);
try
{
    // 获取数组的起始非托管指针
    IntPtr bufferStart = bufferHandle.AddrOfPinnedObject();
    // 计算数组末尾的指针:起始指针 + 元素数量 * 单个uint的字节数(4字节)
    IntPtr ptr = bufferStart + outputBuffer.Length * sizeof(uint);

    // 反向遍历输入数据,调用编码函数
    for(int i = input.Length; i > 0; i--)
    {
        int s = input[i - 1];
        // 传递ptr的引用,函数会修改ptr的值(向前移动)
        RansWrapper.Rans64EncPutSymbol(ref ransState, ref ptr, ref esyms[s]);
    }

    // 刷新编码器,同样传递ptr的引用
    RansWrapper.Rans64EncFlush(ref ransState, ref ptr);

    // 此时ptr指向编码后数据的起始位置,可计算有效数据长度
    int encodedLength = (int)((bufferStart + outputBuffer.Length * sizeof(uint) - ptr) / sizeof(uint));
}
finally
{
    // 必须释放GCHandle,避免内存泄漏
    bufferHandle.Free();
}

关键说明

  • 固定数组内存:用GCHandle.Alloc固定托管数组后,GC不会再移动该数组的内存位置,确保指针始终有效。
  • 指针计算:数组末尾指针的计算逻辑和C完全一致:起始指针 + 元素总数 * 元素字节数,对应C中out_buf + out_max_elems的地址偏移逻辑。
  • 传递指针的引用:用ref IntPtr传递指针,对应C++的uint32_t**,这样函数内部修改指针的值时,C#中的ptr变量会同步更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:04:55