У меня есть следующая функция 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;
}
И, соответствующая декларация функции extern в С#:
[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
вызывает нарушение прав доступа, но я не могу понять, как и почему, и поэтому я считаю, что, возможно, маршаллинг что-то происходит не так.
Спасибо.
Параметр массива объявлен неверно. AС# array уже является ссылкой, поэтому вам не нужен ref
. Объявите это следующим образом:
[DllImport(InteropUtils.RUNTIME_DLL, EntryPoint = "GetResolutionArray",
CallingConvention = CallingConvention.Cdecl)]
internal static extern bool _GetResolutionArray(int adapterIndex,
int outputIndex, uint resolutionArrayLength, Resolution[] resolutions);