【问题标题】:PInvoke Array Marshalling FailurePInvoke 阵列编组失败
【发布时间】:2014-03-01 01:05:22
【问题描述】:

我在 DLL 中导出了以下 C++ 函数:

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 的调用导致了访问冲突,但我不知道是如何或为什么,因此我推断可能编组在某个地方出错了。

谢谢。

【问题讨论】:

  • 尝试只编组 OUT 而不是 in 和 out 作为返回参数。另外,什么是 EnginePipeline.TerminateWithError()?我会软化这一点,并确保在此处的问题中添加完整的错误消息。
  • @ebyrob 试过了,没效果。
  • 可能sizeof(Resolution) C++sizeof(Resolution) C# 不同。
  • @wdosanjos 我在 C# 和 C++ 端打印了 sizeof(Resolution),都是 16 个字节。
  • 从 C# 声明中删除 ref,数组已经通过引用传递。

标签: c# c++ pinvoke memcpy


【解决方案1】:

数组参数声明不正确。 C# 数组已经是一个引用,因此您不需要ref。像这样声明它:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 2014-12-26
    • 2012-07-17
    • 2020-12-26
    • 1970-01-01
    相关资源
    最近更新 更多