ما هي القيم التي يجب إرجاعها لـ S_OK أو E_FAIL من كود c# .net؟

StackOverflow https://stackoverflow.com/questions/362861

  •  21-08-2019
  •  | 
  •  

سؤال

أقوم بتنفيذ واجهة COM التي يجب أن تُرجع قيم int أيضًا S_OK أو E_FAIL.أنا بخير العودة S_OK عندما أستعيد ذلك من مكالمة أخرى (Marshal.QueryInterface)، ولكن إذا أردت إرجاع قيمة فشل، فما هي القيمة الفعلية التي أستخدمها؟ E_FAIL?

(إنه سؤال أساسي أساسي يصعب العثور على إجابة له)

بافتراض أنه رقم محدد محدد في Win32 API، هل هناك طريقة لاستخدامه ضمن كود .net دون الإعلان عن الثابت الخاص بي؟

شكرًا!

التحديث (الإجابة أدناه):

ربما أكون غطاسًا تمامًا، لكني أواجه مشاكل مع هذا.وفقًا لـ Platform SDK الخاص بي، فإن HRESULT عبارة عن عدد صحيح بتوقيع 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_يفشل؛ ... تنهد

حل نهائي:

أفعل ذلك الآن عن طريق الحصول على تعداد HRESULT (الضخم ولكن المفيد جدًا) من pinvoc.net وإضافته إلى الحل الخاص بي.ثم استخدمه شيئًا مثل هذا:

return HRESULT.S_OK;
هل كانت مفيدة؟

المحلول

E_FAIL هو Hex 80004005 في WinError.h

يمكنك رؤية كامل ملف WinError.h هنا.ليس عليك تثبيت C++ فقط لرؤية القيم.

تحديث:

تعد الإصدارات الموقعة وغير الموقعة من 0x80004005 مجرد تمثيلين لنفس قناع البت.إذا كنت تحصل على خطأ في الإرسال، فاستخدم القيمة السالبة الموقعة.عندما يلقي على الأمم المتحدة موقعة طويلة ستكون القيمة "الصحيحة".اختبر هذا بنفسك في C#، سوف يعمل على سبيل المثال

هذا الرمز

    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();
    }

سوف تنتج هذا الإخراج

  • غير موقعة 2147500037
  • تم التوقيع -2147467259
  • تم التوقيع كغير موقع 2147500037

لذا فمن الآمن استخدام -2147467259 لقيمة E_FAIL

نصائح أخرى

من WinError.h لـ Win32

#define E_FAIL _HRESULT_TYPEDEF_(0x80004005L)

للعثور على إجابات مثل هذه، استخدم البحث عن الملفات في Visual Studio للبحث في ملفات الرأس في دليل VC Include الخاص بدليل تثبيت الاستوديو المرئي الخاص بك.

C:\Program Files\Microsoft Visual Studio 9.0\VC\include

استخدم الكلمة الأساسية "غير المحددة" للقيام بذلك.

على سبيل المثال

const int E_FAIL = unchecked((int)0x80004005);

VSConstans ربما تريد أن تريد:

الحقل VSConstans.S_OK

HRESULT عام للنجاح.

مساحة الاسم:مايكروسوفت فيجوال ستوديو

حَشد:Microsoft.VisualStudio.Shell.10.0 (في Microsoft.VisualStudio.Shell.10.0.dll)

لقد استخدمت هذا:

const int EFail = int.MinValue + 0x00004005;

للتسوية بين سهولة القراءة (إذا كنت معتادًا على الرموز السداسية) وتقييد C#.

يجب عليك تنزيل النظام الأساسي 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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top