عند استدعاء وظائف Windows API من C#، أي مصدر للتوقيعات إلى الثقة: .NET Framework Source Code أو Pinvoke؟
-
29-09-2019 - |
سؤال
على سبيل المثال ، هذا من ملف مصدر إطار عمل .NET UnsafenativeMethods.cs:
[DllImport(ExternDll.User32, ExactSpelling=true, CharSet=CharSet.Auto)]
public static extern bool GetWindowRect(HandleRef hWnd,
[In, Out] ref NativeMethods.RECT rect);
وهذا من pinvoke.net:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(HandleRef hwnd, out RECT lpRect);
ما هو التوقيع الصحيح/الأفضل لهذه الوظيفة؟ (واحد منهم فقط لديه
[return: MarshalAs(UnmanagedType.Bool)]
, ، أو[In, Out] ref
, ، إلخ.)لقد لاحظت ذلك في ملفات مصدر إطار عمل في .NET
ExactSpelling=true, CharSet=CharSet.Auto
, ، لكن على بينفوك لا يفعلون ذلك. هل هذا مطلوب؟
المحلول
كلاهما سوف ينجزون المهمة. هناك أكثر من طريقة للجلد قطة Pinvoke. على وجه التحديد لهذا المثال:
ExactSpelling=true
هو تحسين ، فهو يتجنب وجود pinvoke marshaller يبحث عنGetWindowRectA
وGetWindowRectW
الإصدارات. إنها غير موجودة لوظيفة واجهة برمجة التطبيقات هذه لأنها لا تأخذ وسيطة سلسلة. رؤية اختلاف فعلي في وقت التشغيل ستكون معجزة.CharSet=CharSet.Auto
هي دائما فكرة جيدة لأن الافتراضي (ANSI) غير فعال للغاية. يحدث فقط عدم إحداث أي فرق هنا لأن الوظيفة لا تأخذ أي وسيطات سلسلة.[In, Out]
غير ضروري لأن هذا هو الافتراضي لنوع قابل للضرب. كلمة باهظة الثمن تعني أن Pinvoke Marshaller يمكنه تمرير مؤشر مباشرة إلى الذاكرة المدارة ، لا يلزم تحويل. كفاءة قدر الإمكان. نفس الفكرةCharSet
على الرغم من أن كونك صريحًا بشأن ذلك يساعد على إنشاء رمز توثيق ذاتي وتذكر التعامل مع الحالة غير العادية. القدرة على الاستخدام فقط[In]
أو[Out]
يمكن أن يكون تحسينًا مهمًا ، ليس هنا لأنه تم تحسينه بالفعل. FWIW ، [Out] كان الخيار الصحيح.out
ضدref
, ، نفس الفكرة على النحو الوارد أعلاه. استخدامout
هو أكثر صحة لأن واجهة برمجة التطبيقات لا تستخدم بالفعل أي قيم تم تمريرها داخلRECT
. ومع ذلك ، فإنه لا يحدث أي فرق في وقت التشغيل لأن برنامج التحويل البرمجي JIT يهيئ دائمًا على أي حال.[return: MarshalAs(UnmanagedType.Bool)]
ليس ضروريًا ، إنه التنظيم الافتراضي لنوافذBOOL
. لست متأكدًا من سبب تشمله pinvoke.net دائمًا.
لذلك باختصار ، لا مثالي لكنهما سيعملان. هذه هي مخاطر بينفوك.