2016-02-25 4 views
1

Сейчас я оберточной Un4seen BASS аудио библиотеки в .NETMarshal BOOL возвращение пользовательского Return <bool>

функции BASS возвращает значение bool, требует проверки LastError знать ошибки, которая произошла, если возвращается ложь.

Так я реализовал Return<T> класс, чтобы сделать его объектно-ориентированный:

using ManagedBass.Dynamics; 

namespace ManagedBass 
{ 
    /// <summary> 
    /// Wraps a Bass Error in a function return value 
    /// </summary> 
    /// <typeparam name="T">The Type of the function return value</typeparam> 
    public class Return<T> 
    { 
     public Errors ErrorCode { get; } 

     Return(T Value) 
     { 
      ErrorCode = Bass.LastError; 
      this.Value = Value; 
     } 

     public T Value { get; } 

     public static implicit operator T(Return<T> e) => e.Value; 

     public static implicit operator Return<T>(T e) => new Return<T>(e); 

     public bool Success => ErrorCode == Errors.OK; 
    } 
} 

Теперь методы, как:

[DllImport(DllName, EntryPoint = "BASS_StreamFree")] 
public static extern bool StreamFree(int Handle); 

Я бы вместо этого хочу вернуть Return<bool>, так что пользователь может легко проверьте ErrorCode объектно-ориентированным способом.

Теперь, вы можете сказать, что я создаю еще один метод, как:

// bool implicitly converts to Return<bool> 
public static Return<bool> StreamFree2(int Handle) => StreamFree(Handle) 

Но, проблема в том, что уже есть тысячи DllImports и делать это для всех из них был бы кошмар.

Итак, я попробовал:

[DllImport(DllName, EntryPoint = "BASS_StreamFree")] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern Return<bool> StreamFree(int Handle); 

Составлен, но не работает.

Может ли кто-нибудь указать мне, где я ошибаюсь или что-то подобное возможно.

Спасибо заранее.

ответ

2

Нет способа сделать это без функции обертки письма. Вы не можете просто изменить возвращаемый тип функции. Маршаллер не сможет автоматически создать новый объект Return<T>. Ваша последняя попытка объявления указывает маршаллеру, что функция возвращает BOOL, но функция не объявляется как возвращающая BOOL. Очевидно, что это не сработает; он не работает во время выполнения, когда обнаружено несоответствие.

Возможна и другая проблема. Я не знаю, какой тип функции библиотеки BASS фактически возвращает, но если это bool, то UnmanagedType.Bool - неправильный тип. Вы действительно хотите UnmanagedType.U1. UnmanagedType.Bool относится к 4-байтовому типу BOOL, который на самом деле является целым числом. UnmanagedType.U1 относится к 1 байту C++ bool.

В целом, я не думаю, что ваш «объектно-ориентированный» подход мог бы предложить какое-либо реальное преимущество. Конечно, вы возвращаете объект, но код клиента, который вы пишете, не будет выглядеть иначе, потому что вам все равно придется проверять код ошибки каждый раз.

Элегантный, совместимый с .NET дизайн создаст исключение, когда функция библиотеки вернет ошибку. Это исключение (BassException или что-то еще) обернет код ошибки. Конечно, для этого потребуются функции обертки для каждой из функций библиотеки, но по крайней мере будет некоторая выплата после того, как вы закончите. Рассмотрим автоматизацию генерации таких функций с помощью инструмента.

+0

Благодарим вас за подробный ответ. –

+0

BTW Есть ли способ получить функцию, вызванную после вызова каждой функции –

+0

Я слышал что-то подобное о CodeContracts.Могу ли я использовать это, чтобы выбросить Exception –

 Смежные вопросы

  • Нет связанных вопросов^_^