【发布时间】: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,数组已经通过引用传递。