عند استدعاء وظائف Windows API من C#، أي مصدر للتوقيعات إلى الثقة: .NET Framework Source Code أو Pinvoke؟

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

سؤال

على سبيل المثال ، هذا من ملف مصدر إطار عمل .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);
  1. ما هو التوقيع الصحيح/الأفضل لهذه الوظيفة؟ (واحد منهم فقط لديه [return: MarshalAs(UnmanagedType.Bool)], ، أو [In, Out] ref, ، إلخ.)

  2. لقد لاحظت ذلك في ملفات مصدر إطار عمل في .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 دائمًا.

لذلك باختصار ، لا مثالي لكنهما سيعملان. هذه هي مخاطر بينفوك.

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