Какие значения возвращаются для S_OK или E_FAIL из кода С#.net?
Я реализую COM-интерфейс, который должен возвращать значения int S_OK
или E_FAIL
. Я нормально возвращаю S_OK
, поскольку получаю это от другого вызова (Marshal.QueryInterface), но если я хочу вернуть значение отказа, какое фактическое значение я использую для E_FAIL
?
(Это такой фундаментальный фундаментальный вопрос, что трудно найти ответ)
Предполагая, что это конкретный номер, определенный в Win32 API, есть способ использовать его внутри .net-кода без объявления моей собственной константы?
спасибо!
Обновление (см. ниже):
Может быть, я полный плункер, но у меня проблемы с этим. Согласно моей платформе SDK, HRESULT является LONG, который представляет собой 32-разрядное целое число со знаком, верно? Таким образом, возможные значения -2,147,483,648 до 2,147,483,647. Но 0x80004005 = 2,147,500,037, что составляет > 2,147,483,647. Что дает!?
Это означает, что когда я пытаюсь поместить это в свой код:
const int E_FAIL = 0x80004005;
Я получаю ошибку компилятора Невозможно неявно преобразовать тип 'uint' в 'int'.
Обновление 2:
Я собираюсь объявить это следующим образом:
const int E_FAIL = -2147467259;
потому что если я попытаюсь сделать что-то вроде этого:
const UInt32 E_FAIL = 0x80004005;
return (Int32)E_FAIL;
Я получаю ошибку компилятора. Значение константы "2147500037" не может быть преобразовано в "int" (используйте "непроверенный" синтаксис для переопределения)
Уф! Кто знал, насколько сложно было бы объявить стандартное возвращаемое значение.... Где-то должен быть класс, скрывающийся, что я должен был бы использовать как вернуть Win32ReturnCodes.E _
FAIL;... вздох
ULTIMATE SOLUTION:
Теперь я сделаю это, получив (массивное, но очень полезное) перечисление HRESULT из pinvoke.net и добавив его в мое решение. Затем используйте его примерно так:
return HRESULT.S_OK;
Ответы
Ответ 1
E_FAIL - Hex 80004005 в WinError.h
Здесь вы можете увидеть полный файл WinError.h. Вам не нужно устанавливать С++ только для просмотра значений.
UPDATE:
Подписанные и неподписанные версии 0x80004005 представляют собой два представления одной и той же битовой маски. Если вы получаете ошибку кастинга, используйте отрицательное значение со знаком. Когда он будет подписан в ООН, это будет "правильное" значение. Проверьте это самостоятельно на С#, это сработает
например.
Этот код
static void Main(string[] args)
{
UInt32 us = 0x80004005;
Int32 s = (Int32)us;
Console.WriteLine("Unsigned {0}", us);
Console.WriteLine("Signed {0}", s);
Console.WriteLine("Signed as unsigned {0}", (UInt32)s);
Console.ReadKey();
}
будет выдавать этот вывод
- Unsigned 2147500037
- Подписано -2147467259
- Подписан как unsigned 2147500037
Таким образом, безопасно использовать -2147467259 для значения E_FAIL
Ответ 2
Из WinError.h для Win32
#define E_FAIL _HRESULT_TYPEDEF_(0x80004005L)
Чтобы найти ответы, подобные этому, используйте визуальный просмотр файлов студии для поиска файлов заголовков в каталоге VC Include в каталоге установки вашей студии.
C:\Program Files\Microsoft Visual Studio 9.0\VC\include
Ответ 3
Для этого используйте ключевое слово "unchecked".
например.
const int E_FAIL = unchecked((int)0x80004005);
Ответ 4
VSConstants может вам понадобиться:
Поле VSConstants.S_OK
Общий HRESULT для успеха.
Пространство имен: Microsoft.VisualStudio
Сборка: Microsoft.VisualStudio.Shell.10.0 (в Microsoft.VisualStudio.Shell.10.0.dll)
Ответ 5
Я использовал это:
const int EFail = int.MinValue + 0x00004005;
чтобы скомпрометировать читаемость (если вы используете шестнадцатеричные коды) и ограничение С#.
Ответ 6
Вы должны загрузить платформу SDK (ссылка)
Я просмотрел код и нашел следующее в winerror.h
typedef long HRESULT;
#ifdef RC_INVOKED
#define _HRESULT_TYPEDEF_(_sc) _sc
#else // RC_INVOKED
#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
#endif // RC_INVOKED
#define E_FAIL _HRESULT_TYPEDEF_(0x80004005L)
#define S_OK ((HRESULT)0x00000000L)
Вы должны вернуть E_FAIL вместо значения. Просто включите winerror.h.