DLLIMPORT - Preserversig و SetLasterRor السمات
سؤال
على MSDN لقد وجدت الوصف التالي للسمات الثانية:
الحفاظ على قم بتعيين حقل Preservesig إلى True لترجمة التوقيعات غير المدارة مباشرة مع قيم HRESULT أو RETVAL؛ قم بتعيينه على FALSE لتحويل قيم HRESULT أو RETVAL تلقائيا إلى استثناءات. بشكل افتراضي، يكون حقل Preservesig صحيحا.
setlasterror. تمكن المتصل لاستخدام وظيفة API Marshal.getlastwin32error لتحديد ما إذا كان حدث خطأ أثناء تنفيذ الطريقة. في Visual Basic، الافتراضي صحيح (الذي يضيف بعض النفقات العامة)؛ في C # و C ++، الافتراضي هو خطأ.
سؤالي هو: كيف يرتبط هذين اثنين ببعضهما البعض؟ لنفترض أنني أعطيت محمية "FALSER" - فهذا يعني أنه يجب أن يكون لدي HRESULT تحويلها إلى استثناء - إذا عودة الدالة غير المدارة عدد صحيح يشير إلى وجود خطأ أو لا حدث خطأ، فكيف يمكن ترجمة هذا إلى استثناء؟
أيضا لماذا أحتاج إلى استدعاء الأسلوب GetLastWin32Error إذا تمكنت بطريقة أو بأخرى من استخراج الاستثناء باستخدام Preservesig؟
نوع التحيات PK.
المحلول
Win32 وظائف لا تعيد تقريبا HRESULT
. وبعد بدلا من ذلك يعودون BOOL
أو استخدم قيم خاصة للإشارة إلى الخطأ (على سبيل المثال CreateFile
عائدات INVALID_HANDLE_VALUE
). يخزنون رمز الخطأ في متغير لكل ترابط، والذي يمكنك قراءته GetLastError()
. SetLastError=true
يرشد Marshaler قراءة هذا المتغير بعد إرجاع الوظيفة الأصلية، و Stash رمز الخطأ حيث يمكنك قراءته لاحقا Marshal.GetLastWin32Error()
. وبعد هذه الفكرة هي أن وقت التشغيل .NET قد يسميه وظائف Win32 الأخرى وراء الكواليس الذي يفوض رمز الخطأ من مكالمة P / Invoke قبل أن تحصل على فرصة لتفقدها.
وظائف التي ترجع HRESULT
(أو ما يعادلها، على سبيل المثال NTSTATUS
) تنتمي إلى مستوى مختلف من التجريد من وظائف Win32. عموما هذه الوظائف ترتبط كوم (أعلاه Win32) أو من ntdll
(أدناه Win32)، لذلك لا يستخدمون رمز الخطأ Win32 الأخير (قد يتصلون بوظائف Win32 داخليا، على الرغم من).
PreserveSig=false
يرشد المنشاهير للتحقق من العودة HRESULT
وإذا لم يكن رمز النجاح، لإنشاء ورمي استثناء يحتوي على HRESULT
. وبعد الإعلان المدار الخاص بك DllImport
وظيفة إد ثم void
كما نوع العودة الخاصة به.
تذكر، لا يمكن لجهاز التحويل البرمجي C # أو VB التحقق من DllImport
التوقيع غير المدعوم من وظيفة ED، لذلك يجب أن يثق بكل ما تخبره به. إذا وضعت PreserveSig=false
على وظيفة ترجع شيئا آخر غير HRESULT
, ، سوف تحصل على نتائج غريبة (مثل استثناءات عشوائية). إذا وضعت SetLastError=true
على وظيفة لا تحدد رمز الخطأ Win32 الأخير، ستحصل على القمامة بدلا من رمز خطأ مفيد.