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

使用Marshal.Copy从IntPtr复制到Double[]时出现Access Violation Error如何解决

代码错误原因
  • 参数语义完全不匹配:你C代码中第二个参数double* pSamples的语义是「调用方提前分配好对应长度的double数组内存,把数组首地址传入,C负责往这段已分配的内存写值」。但你C#的DllImport声明中将该参数写为out IntPtr pSamples,相当于给C传入的是IntPtr变量的内存地址(即二级指针),C把这个二级指针的值当成double数组的首地址直接写入,本质是往随机的非法内存地址写数据,直接触发访问冲突。
  • 基础语法错误:
    • DllImport声明中返回值拼写错误,应为void而非voi
    • C#中指针类型拼写错误,应为IntPtr而非Intptr,变量名Sample和后续Marshal.Copy调用时的Samples拼写不一致
修复方案

方案1(推荐:C#分配托管内存,无内存泄漏风险)

不需要手动调用Marshal.Copy,运行时会自动处理封送,C++代码不需要修改,仅修改C#代码即可:

// 修改DllImport声明,直接传入double数组,加[Out]特性告知运行时需要把C++侧修改的内容回写到托管数组
[DllImport("LibOperation.dll", CallingConvention = CallingConvention.Cdecl)]
static public extern void FillDoubleValues(ulong _NumSamplesToCapture, [Out] double[] pSamples);

void Main()
{
    ulong NumSamplesToCapture = 5000;
    double[] ys1 = new double[NumSamplesToCapture];
    // 直接传入托管数组即可
    FillDoubleValues(NumSamplesToCapture, ys1);
    // 直接使用ys1即可
}

方案2(C++分配非托管内存,C#读取后手动释放)

如果你的业务逻辑要求必须由C分配内存,需要同时修改C和C#代码:

修改后的C++代码

// 注意第二个参数改为二级指针,必须用CoTaskMemAlloc分配内存,C#的Marshal才能正常读取和释放
__declspec(dllexport) void FillDoubleValues(IN ULONG64 _NumSamplesToCapture, OUT double** pSamples)
{
    *pSamples = (double*)CoTaskMemAlloc(_NumSamplesToCapture * sizeof(double));
    for (int i = 0; i < _NumSamplesToCapture; i++)
    {
        (*pSamples)[i] = (double)rand() / RAND_MAX;
    }
}

修改后的C#代码

[DllImport("LibOperation.dll", CallingConvention = CallingConvention.Cdecl)]
static public extern void FillDoubleValues(ulong _NumSamplesToCapture, out IntPtr pSamples);

void Main()
{
    ulong NumSamplesToCapture = 5000;
    IntPtr pSamples = IntPtr.Zero;
    FillDoubleValues(NumSamplesToCapture, out pSamples);
    
    double[] ys1 = new double[NumSamplesToCapture];
    Marshal.Copy(pSamples, ys1, 0, (int)NumSamplesToCapture);
    // 必须手动释放C++分配的非托管内存,否则会出现内存泄漏
    Marshal.FreeCoTaskMem(pSamples);
    
    // 后续正常使用ys1即可
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:15:01