// License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2017 Intel Corporation. All Rights Reserved. namespace Intel.RealSense { using System; using System.Diagnostics; using System.Runtime.InteropServices; /// <summary> /// Custom marshaler for throwing exceptions on errors codes. /// </summary> public class ErrorMarshaler : ICustomMarshaler { private static ErrorMarshaler Instance; public static ICustomMarshaler GetInstance(string s) { if (Instance == null) { Instance = new ErrorMarshaler(); } return Instance; } public void CleanUpManagedData(object ManagedObj) { } public void CleanUpNativeData(IntPtr pNativeData) { // !TODO: maybe rs_free_error here? NativeMethods.rs2_free_error(pNativeData); } public int GetNativeDataSize() { return IntPtr.Size; } public IntPtr MarshalManagedToNative(object ManagedObj) { return IntPtr.Zero; } public object MarshalNativeToManaged(IntPtr pNativeData) { if (pNativeData == IntPtr.Zero) { return null; } string function = Marshal.PtrToStringAnsi(NativeMethods.rs2_get_failed_function(pNativeData)); string args = Marshal.PtrToStringAnsi(NativeMethods.rs2_get_failed_args(pNativeData)); string message = Marshal.PtrToStringAnsi(NativeMethods.rs2_get_error_message(pNativeData)); ExceptionType type = NativeMethods.rs2_get_librealsense_exception_type(pNativeData); var inner = new ExternalException($"{function}({args})"); switch (type) { case ExceptionType.NotImplemented: throw new NotImplementedException(message, inner); case ExceptionType.WrongApiCallSequence: throw new InvalidOperationException(message, inner); case ExceptionType.InvalidValue: throw new ArgumentException(message, inner); case ExceptionType.Io: throw new System.IO.IOException(message, inner); default: // TODO: custom exception type throw new Exception(message, inner); } } } }