Pinvoke阵列编组失败

PInvoke Array Marshalling Failure

本文关键字:失败 阵列 Pinvoke      更新时间:2023-10-16

i具有以下C 功能在DLL中导出:

extern "C" __declspec(dllexport) bool GetResolutionArray(int32_t adapterIndex, int32_t outputIndex, uint32_t arrayLength, Resolution outResolutionArr[]) {
        memcpy_s(
        outResolutionArr, 
        sizeof(Resolution) * arrayLength,
        RENDER_COMPONENT.GetResolutionArray(adapterIndex, outputIndex),
        RENDER_COMPONENT.GetOutput(adapterIndex, outputIndex).NumResolutions * sizeof(Resolution)
        );
    return true;
}

,在C#中匹配的外部功能声明:

[DllImport(InteropUtils.RUNTIME_DLL, EntryPoint = "GetResolutionArray", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool _GetResolutionArray(int adapterIndex, int outputIndex, uint resolutionArrayLength, [MarshalAs(UnmanagedType.LPArray), In, Out] ref Resolution[] resolutions);

但是,当我尝试使用此功能如下所示时,程序会用fatalexecutionEngineError崩溃(表明我猜我在某处损坏了某些东西)(错误代码0xc0000005,即访问违规):

Resolution[] resolutions = new Resolution[outOutputDesc.NumResolutions];
if (!_GetResolutionArray(outAdapterDesc.AdapterIndex, outOutputDesc.OutputIndex, (uint) resolutions.Length, ref resolutions)) {
    EnginePipeline.TerminateWithError("Internal engine call failed: _GetResolutionArray");
}

我强烈怀疑我对memcpy_s的呼吁正在造成违规访问,但我看不出如何或原因,因此,我认为也许编组在某个地方出错。

谢谢。

数组参数错误地声明。C#数组已经是参考,因此您不需要ref。这样声明:

[DllImport(InteropUtils.RUNTIME_DLL, EntryPoint = "GetResolutionArray", 
    CallingConvention = CallingConvention.Cdecl)]
internal static extern bool _GetResolutionArray(int adapterIndex, 
    int outputIndex, uint resolutionArrayLength, Resolution[] resolutions);