برمجة API. ما هي API وما الغرض منها؟

تحدد واجهة برمجة التطبيقات (API) الوظيفة التي يوفرها البرنامج (وحدة ، مكتبة) ، بينما تسمح لك واجهة برمجة التطبيقات (API) باستخلاص كيفية تنفيذ هذه الوظيفة بالضبط.

إذا كان البرنامج (وحدة ، مكتبة) يعتبر صندوقًا أسود ، فإن واجهة برمجة التطبيقات هي مجموعة من "المقابض" المتاحة لمستخدم هذا الصندوق ، والتي يمكنه قلبها وسحبها.

تتفاعل مكونات البرامج مع بعضها البعض من خلال واجهات برمجة التطبيقات. في هذه الحالة ، تشكل المكونات عادةً تسلسلاً هرميًا - تستخدم المكونات عالية المستوى واجهة برمجة التطبيقات للمكونات منخفضة المستوى ، وهذه بدورها تستخدم واجهة برمجة التطبيقات للمكونات ذات المستوى الأدنى.

وفقًا لهذا المبدأ ، فإن بروتوكولات نقل البيانات عبر. يحتوي بروتوكول الإنترنت القياسي (نموذج شبكة OSI) على 7 طبقات (من الطبقة المادية لنقل حزمة البت إلى طبقة بروتوكولات التطبيق مثل HTTP و IMAP). تستفيد كل طبقة من وظائف طبقة البيانات السابقة وتوفر بدورها الوظيفة المطلوبة للطبقة التالية.

من المهم ملاحظة أن مفهوم البروتوكول قريب من حيث المعنى لمفهوم واجهة برمجة التطبيقات. كلاهما تجريدان للوظائف ، فقط في الحالة الأولى نتحدث عن نقل البيانات ، وفي الحالة الثانية - عن بناء تطبيقات الكمبيوتر.

تتضمن الوظيفة و API لمكتبة الفئة وصفًا التوقيعاتو دلالات الوظيفة.

واجهة برمجة التطبيقات (API) هي واجهة برمجية للتفاعل بين الأنظمة التي تتيح لك:

  • احصل على الوصول إلى خدمات الأعمال التجارية للمؤسسات
  • تبادل المعلومات بين الأنظمة والتطبيقات
  • تبسيط التواصل بين الشركات والشركاء والمطورين والعملاء

استراتيجية واجهة برمجة التطبيقات المفتوحة

تتضمن إستراتيجية API:

  • تطوير منتجات الأعمال على أساس واجهات برمجة التطبيقات الحالية
  • تقديم خدمات داخلية للمطورين
  • نماذج تسييل API لبناء تفاعل متعدد القنوات وزيادة الأرباح

يساعد تطبيق مفهوم Open API على تحويل الأعمال ، وتضمينها في نظام إيكولوجي مرن للمشروع للاعبين في السوق ، وخلق ظروف لتوليد مستمر لأفكار جديدة وخلق قيمة إضافية عند إدارة مصفوفات بيانات الشركة.

يتطور سوق حلول التكامل في سياق تطور واجهات برمجة التطبيقات - من EDI و SOAP إلى Web 2.0 ، والذي بدأ عصر واجهات برمجة التطبيقات العامة. قد يزيد عدد هذه الواجهات في السنوات الثلاث المقبلة بأكثر من 50 مرة ويصل إلى مليون. هذا بسبب تعدد القنوات: يجب أن تتغير قنوات التفاعل مع العملاء معها. أدى النمو المستمر في عدد المستهلكين وحجم البيانات إلى ظهور اقتصاد واجهة برمجة التطبيقات ، مما يساعد على إنشاء نماذج أعمال مبتكرة تعتمد على واجهات مفتوحة لاستخدام أصول وخدمات المؤسسة.

توقيع الوظيفة

توقيع الوظيفة- جزء من الإعلان العام عن الوظيفة ، مما يسمح لوسائل الترجمة بتحديد الوظيفة من بين أمور أخرى. لغات البرمجة المختلفة لها أفكار مختلفة حول توقيع الوظيفة ، والتي ترتبط أيضًا ارتباطًا وثيقًا بإمكانيات التحميل الزائد للوظيفة في هذه اللغات.

في بعض الأحيان يميزون توقيع المكالمةو توقيع التنفيذالمهام. عادةً ما يتم تجميع توقيع الاستدعاء وفقًا للبناء النحوي لاستدعاء الوظيفة ، مع مراعاة توقيع نطاق هذه الوظيفة ، واسم الوظيفة ، وتسلسل الأنواع الفعلية من الوسائط في الاستدعاء ، ونوع نتيجة. يتضمن توقيع التنفيذ عادةً بعض العناصر من البناء النحوي لإعلان الوظيفة: محدد نطاق الوظيفة ، واسمها ، وتسلسل أنواع الوسيطة الرسمية.

على سبيل المثال ، في لغة البرمجة C ++ ، يتم تحديد وظيفة بسيطة بشكل فريد بواسطة المترجم من خلال اسمها وتسلسل أنواع الوسيطات الخاصة بها ، والتي تشكل توقيع الوظيفة في هذه اللغة. إذا كانت الوظيفة طريقة من فئة ما ، فسيشارك اسم الفصل أيضًا في التوقيع.

وتجدر الإشارة أيضًا إلى أن المبرمج غالبًا ما يكون لديه العديد من واجهات برمجة التطبيقات المختلفة تحت تصرفه لتحقيق نفس النتيجة. في هذه الحالة ، يتم تنفيذ كل واجهة برمجة تطبيقات عادةً باستخدام واجهات برمجة التطبيقات لمكونات البرامج بمستوى تجريد أقل.

على سبيل المثال: لكي ترى السطر "Hello، world!" كل ما عليك فعله هو إنشاء مستند HTML مع الحد الأدنى من العنوان ونص بسيط يحتوي على السلسلة المحددة. ماذا يحدث عندما يفتح المستعرض هذا المستند؟ سيقوم برنامج المتصفح بتمرير اسم الملف (أو واصف ملف مفتوح بالفعل) إلى المكتبة التي تعالج مستندات HTML ، والتي بدورها تستخدم واجهة برمجة التطبيقات نظام التشغيليقرأ هذا الملف ويفهم جهازه ، ويستدعي من خلال واجهة برمجة التطبيقات الخاصة بمكتبة العناصر الأساسية الرسومية القياسية مثل عمليات مثل "مسح النافذة" ، "الكتابة بالخط المحدد مرحباً ، أيها العالم!" ستتحول هذه المكتبة إلى واجهة برمجة تطبيقات نظام التشغيل مع الطلبات مثل "ضع هذا في المخزن المؤقت لبطاقة الفيديو".

في الوقت نفسه ، هناك بالفعل العديد من واجهات برمجة التطبيقات البديلة الممكنة في كل مستوى تقريبًا. على سبيل المثال: يمكننا كتابة المستند المصدر ليس بتنسيق HTML ، ولكن في LaTeX ، يمكننا استخدام أي متصفح للعرض. تستخدم المتصفحات المختلفة بشكل عام مكتبات HTML مختلفة ، وإلى جانب ذلك ، يمكن (بشكل عام) بناؤها باستخدام مكتبات بدائية مختلفة وأنظمة تشغيل مختلفة.

وبالتالي ، فإن التعقيدات الرئيسية لأنظمة API ذات الطبقات الحالية هي:

  • صعوبة في نقل كود البرنامج من نظام API إلى آخر (على سبيل المثال ، عند تغيير نظام التشغيل) ؛
  • فقدان الوظيفة عند الانتقال من مستوى أدنى إلى مستوى أعلى. بشكل تقريبي ، يتم إنشاء كل "طبقة" من واجهة برمجة التطبيقات لتسهيل تنفيذ مجموعة قياسية من العمليات. ولكن في الوقت نفسه ، يصبح من الصعب حقًا ، أو يصبح من المستحيل بشكل أساسي ، إجراء بعض العمليات الأخرى التي يوفرها مستوى أقل من واجهة برمجة التطبيقات.

أنواع API الأساسية

واجهات برمجة التطبيقات الداخلية

  • الوصول إلى API يقتصر على المطورين الداخليين
  • تستهدف التطبيقات موظفي المؤسسة

سائقي عمل:

  • اتساق التنمية
  • تقليل التكاليف
  • تحسين كفاءة التنمية

واجهات برمجة التطبيقات للشريك

  • واجهات برمجة التطبيقات متاحة فقط مجموعة محدودةشركاء العمل
  • تطبيقات مصممة للمستهلكين النهائيين ومستخدمي الأعمال

سائقي عمل:

  • أتمتة عملية التطوير
  • تطوير الشراكات
  • تحسين عملية التفاعل مع الشركاء

واجهات برمجة التطبيقات العامة

يُمنح الوصول إلى أي مطور خارجي ، وتهدف التطبيقات إلى المستخدمين النهائيين

سائقي عمل:

  • تطوير خدمات جديدة
  • تطوير النظام البيئي
  • تفاعل متعدد القنوات

أشهر واجهات برمجة التطبيقات

واجهات برمجة تطبيقات نظام التشغيل

واجهات برمجة تطبيقات واجهة المستخدم الرسومية

  • Direct3D (جزء من DirectX)
  • DirectDraw (جزء من DirectX)

Windows API - مجموعة من وظائف نظام التشغيل

يبدو أن اختصار API للعديد من المبرمجين المبتدئين غامض للغاية وحتى مخيف. في الواقع ، تعد واجهة برمجة التطبيقات (API) مجرد مجموعة من الوظائف الجاهزة التي يمكن لمطوري التطبيقات استخدامها. بشكل عام ، هذا المفهوم يعادل ما كان يطلق عليه غالبًا مكتبة الإجراءات الفرعية. ومع ذلك ، عادة ما يتم فهم API على أنها فئة خاصة من هذه المكتبات.

أثناء تطوير أي تطبيق معقد تقريبًا (MyApplication) ، يتم تكوين مجموعة من الوظائف الداخلية المحددة للمستخدم النهائي ، والتي تُستخدم لتنفيذ هذا البرنامج المعين ، والذي يسمى MyApplication API. ومع ذلك ، غالبًا ما يتضح أنه يمكن استخدام هذه الوظائف بشكل فعال لإنشاء تطبيقات أخرى ، بما في ذلك المبرمجين الآخرين. في هذه الحالة ، يجب على المؤلفين ، بناءً على استراتيجية الترويج لمنتجهم ، أن يقرروا ما إذا كانوا يفتحون الوصول إلى هذه المجموعة للمستخدمين الخارجيين أم لا؟ إذا كانت الإجابة بنعم ، في وصف حزمة البرامج ، تظهر العبارة كخاصية إيجابية: "تتضمن الحزمة مجموعة مفتوحة من وظائف API" (ولكن في بعض الأحيان مقابل أموال إضافية).

وبالتالي ، في أغلب الأحيان ، تشير API إلى مجموعة من الوظائف التي تعد جزءًا من تطبيق واحد ، ولكنها في نفس الوقت متاحة للاستخدام في برامج أخرى. على سبيل المثال ، يحتوي Excel ، بالإضافة إلى واجهة المستخدم النهائي ، على مجموعة وظائف Excelواجهة برمجة تطبيقات يمكن استخدامها ، على وجه الخصوص ، عند إنشاء تطبيقات باستخدام VB.

وفقًا لذلك ، فإن Windows API عبارة عن مجموعة من الوظائف التي تعد جزءًا من نظام التشغيل نفسه ومتاحة في نفس الوقت لأي تطبيق آخر ، بما في ذلك تلك المكتوبة باستخدام VB. في هذا الصدد ، فإن التشابه مع مجموعة مقاطعة نظام BIOS / DOS ، والذي هو في الواقع واجهة برمجة تطبيقات DOS ، له ما يبرره تمامًا.

يكمن الاختلاف في حقيقة أن تكوين وظائف Windows API ، من ناحية ، أوسع بكثير مقارنة بـ DOS ، من ناحية أخرى ، لا يتضمن العديد من أدوات الإدارة المباشرة لموارد الكمبيوتر التي كانت متاحة لـ المبرمجين في نظام التشغيل السابق. بالإضافة إلى ذلك ، يتم الوصول إلى واجهة برمجة تطبيقات Windows باستخدام استدعاءات إجرائية عادية ، ويتم استدعاء وظائف DOS من خلال تعليمات جهاز خاصة للمعالج ، والتي تسمى المقاطعة ("المقاطعة").

لماذا تحتاج Win API لمبرمجي VB

على الرغم من حقيقة أن VB لديها مجموعة كبيرة ومتنوعة من الوظائف ، في عملية تطوير أكثر أو أقل خطورة ، اتضح أن قدراتهم غالبًا ما تكون غير كافية لحل المهام الضرورية. في الوقت نفسه ، غالبًا ما يبدأ المبرمجون المبتدئون في الشكوى من عيوب VB والتفكير في تغيير الأدوات ، دون الشك في أن جهاز الكمبيوتر الخاص بهم يحتوي على مجموعة ضخمة من الأدوات وتحتاج فقط إلى معرفة كيفية استخدامها.

عند التعرف على Win API ، اتضح أن العديد من وظائف VB المضمنة ليست أكثر من استدعاء لإجراءات النظام المقابلة ، ولكن يتم تنفيذها فقط في شكل بناء الجملة لغة معينة. مع وضع هذا في الاعتبار ، الحاجة استخدام APIالمعرفة على النحو التالي:

  1. وظائف API التي يتم تنفيذها بالكامل كوظائف VB مضمنة. ومع ذلك ، في بعض الأحيان يكون من المفيد في هذه الحالة التبديل إلى استخدام واجهة برمجة التطبيقات ، حيث يمكن أن يؤدي ذلك في بعض الأحيان إلى تحسين الأداء بشكل كبير (على وجه الخصوص ، بسبب عدم وجود تحويلات غير ضرورية للمعلمات التي تم تمريرها).
  2. لا تنفذ وظائف VB المدمجة إلا حالة خاصة لوظيفة API المقابلة. هذا خيار شائع إلى حد ما. على سبيل المثال ، يعد CreateDirectory API أقوى من عبارة VB MkDir المضمنة.
  3. عدد كبير من وظائف API ليس لها نظائر على الإطلاق في الإصدار الحالي من لغة VB. على سبيل المثال ، لا يمكنك حذف دليل باستخدام VB - تحتاج إلى استخدام وظيفة DeleteDirectory للقيام بذلك.

يجب التأكيد أيضًا على أن بعض وظائف API (حصتها في Win API صغيرة جدًا) لا يمكن استدعاؤها من برامج VB بسبب عدد من قيود اللغة ، على سبيل المثال ، بسبب عدم القدرة على العمل مع عناوين الذاكرة. ولكن في بعض الحالات ، يمكن أن تساعد تقنيات البرمجة غير التافهة (على وجه الخصوص ، في حالة نفس العناوين).

وجهة نظر المؤلف الشخصية هي أنه بدلاً من التوسع من إصدار إلى إصدار من الوظائف المضمنة لـ VB ، يجب على المرء أن يعطي وصف جيدوظائف API الأكثر شيوعًا. في الوقت نفسه ، أود أن أنصح المطورين بعدم انتظار الظهور نسخة جديدةأدوات ذات وظائف متقدمة ، ولإلقاء نظرة فاحصة على تكوين Win API الحالي - من المحتمل أن الميزات التي تحتاجها يمكن تنفيذها بالفعل في إصدار VB 1.0 من إصدار 1991.

كيف تتعلم Win API

هذا ليس سؤالًا سهلاً ، نظرًا لأن عدد وظائف Win32 API يقدر بحوالي 10000 (لا أحد يعرف الرقم الدقيق ، ولا حتى Microsoft).

يتضمن VB (الإصدارات 4-6) ملفًا مع وصف لإعلانات Win API - WIN32API.TXT (المزيد حول استخدامه لاحقًا). ولكن ، أولاً ، يمكن استخدامه للحصول على معلومات حول الغرض من وظيفة معينة ومعلماتها فقط من خلال أسماء الذاكرة المستخدمة ، وثانيًا ، قائمة الوظائف في هذا الملف بعيدة عن الاكتمال. في وقت واحد (قبل سبع سنوات) ، كان لدى VB 3.0 ملفات تعليمات خاصة تصف وظائف Win16 API. ومع ذلك ، فقد اختفت بالفعل في الإصدار 4.0 هذه المعلومات المفيدة ذات الواجهة المريحة.

يمكن العثور على معلومات شاملة حول Win32 API بتنسيق نظام المساعدةمجموعة أدوات تطوير برامج النظام الأساسي ، والتي توجد على وجه الخصوص في الأقراص المضغوطة الخاصة بمكتبة MSDN المضمنة في VB 5.0 و 6.0 Enterprise Edition و Office 2000 Developer Edition. ومع ذلك ، ليس من السهل العثور على المعلومات الضرورية وفهمها. ناهيك عن حقيقة أن جميع الأوصاف المقدمة تتعلق بلغة C.

الدليل المشهور عالميًا لتعلم برمجة API في بيئة VB هو كتب الخبير الأمريكي الشهير Daniel Appleman. سلسلة دان أبليمان له البصرية الأساسيةكان دليل المبرمج لواجهة برمجة تطبيقات Windows (لـ Win16 ، Win32 ، فيما يتعلق بالإصدارات المختلفة من VB) دائمًا من بين أكثر البرامج مبيعًا لمبرمجي VB منذ عام 1993. تم إحضار دليل VB 5.0 للمبرمجين لـ Win32 API من Dan Appleman ، الذي تم إصداره في عام 1997 ، إلى المؤلف من الولايات المتحدة من قبل صديق وجده في أول مكتبة لبيع الكتب في بلدة إقليمية صغيرة.

يتكون هذا الكتاب من أكثر من 1500 صفحة ويتضمن تقنيات برمجة VB API عامة ، بالإضافة إلى أكثر من 900 وظيفة. يحتوي القرص المضغوط المصاحب على النص الكامل للكتاب وجميع أمثلة البرمجة ، بالإضافة إلى بعض الفصول الإضافية غير المدرجة في النسخة المطبوعة. في عام 1999 ، أصدر Dan Appleman كتابًا جديدًا ، كتاب Dan Appleman Win32 API Puzzle and Tutorial for Visual Basic Programmers ، والذي يتضمن معلومات عن 7600 وظيفة أخرى (على الرغم من أنها ليست واسعة النطاق).

Win API ومكتبة الارتباط الديناميكي (DLL)

يتم تطبيق مجموعة Win API كملفات DLL الديناميكية. علاوة على ذلك ، سنتحدث بالفعل عن تقنية استخدام مكتبات DLL في بيئة VB باستخدام مثال المكتبات التي تعد جزءًا من Win API. ومع ذلك ، عند الحديث عن مكتبات DLL ، هناك بعض الأشياء المهمة التي يجب ملاحظتها.

في هذه الحالة ، نعني بـ DLL المتغير التقليدي للمكتبات الديناميكية الثنائية ، والتي توفر وصولاً مباشرًا للتطبيقات إلى الإجراءات الضرورية - الإجراءات الفرعية أو الوظائف (مثلما يحدث عند استدعاء الإجراءات داخل مشروع VB). يمكن إنشاء مثل هذه المكتبات باستخدام أدوات مختلفة: VC ++ و Delphi و Fortran ، باستثناء VB (سنرى ما سيظهر في الإصدار 7.0) - يمكن للأخير فقط إنشاء ActiveX DLLs ، والتي يمكن الوصول إليها من خلال واجهة OLE Automation.

عادةً ما تحتوي ملفات مكتبة الارتباط الديناميكي على ملحق .DLL ، ولكن هذا ليس ضروريًا على الإطلاق (بالنسبة لـ Win16 ، غالبًا ما يتم استخدام ملحق .EXE) ؛ السائقين الأجهزة الخارجيةيشار إليها بـ DRV.

كما لاحظنا بالفعل ، من الصعب تحديد العدد الدقيق لواجهات برمجة تطبيقات Windows والملفات التي تحتوي عليها ، ولكنها جميعًا موجودة في دليل النظام. في هذا الصدد ، من الأفضل تحديد تكوين المكتبات المضمنة في جوهر نظام التشغيل ، والمكتبات الرئيسية ذات الوظائف الإضافية الرئيسية.

والآن بعض النصائح.

نصيحة 1: تأكد من تنسيق إعلان DL الخاص بك بشكل صحيح L- الإجراءات

تبدو الدعوة إلى إجراءات DLL في البرنامج مماثلة تمامًا لإجراءات Visual Basic "العادية" ، على سبيل المثال:

استدعاء DllName ([قائمة الوسائط])

ومع ذلك ، لاستخدام وظائف DLL الخارجية (بما في ذلك Win API) ، يجب الإعلان عنها في البرنامج باستخدام بيان Declare ، والذي يبدو كالتالي:

تعريف Sub LibProcedureName _ “LibraryName” _ [([ArgumentList])]

قم بتعريف FunctionName _ Lib "LibraryName" _ [([ArgumentList])]

هنا ، يتم إعطاء العناصر الاختيارية للمشغل بين قوسين مربعين ، ومتغيرات التعبير مكتوبة بخط مائل ، وبقية الكلمات عبارة عن كلمات رئيسية. يحتوي نظام المساعدة على وصف جيد جدًا لبناء جملة المشغل ، لذلك سنقوم في الوقت الحالي بتوضيح بعض النقاط.

إعلانات وظائف خارجيةيجب وضعها في قسم الإعلانات العامة للوحدة. إذا قمت بوضعه في وحدة نموذجية ، فيجب عليك تحديد الكلمة الأساسية الخاصة (سيكون هذا الإعلان متاحًا فقط داخل هذه الوحدة النمطية) - هذا هو القيد لجميع إجراءات وحدة النموذج.

يتم تطبيق مجموعة Win32 API فقط كوظائف (كان لدى Win16 API الكثير من الإجراءات الفرعية). بالنسبة للجزء الأكبر ، هذه وظائف من النوع الطويل ، والتي غالبًا ما تُرجع رمز إكمال العملية.

ظهر بيان Declare في MS Basic مرة أخرى في أيام DOS ، كما تم استخدامه للإعلان عن الإجراءات الداخلية للمشروع. في Visual Basic ، هذا غير مطلوب ، لأن إعلان الإجراءات الداخلية يكون تلقائيًا إعلانًا فرعيًا أو إعلانًا وظيفيًا. مقارنة بـ Basic / DOS ، من الضروري تحديد اسم ملف المكتبة في الوصف الجديد حيث يوجد الإجراء المطلوب. توجد مكتبات Wip API في دليل نظام Windows ، لذلك يكفي إعطاء اسم الملف فقط. إذا كنت تقوم بالوصول إلى ملف DLL موجود في موقع عشوائي ، فأنت بحاجة إلى الكتابة مسار كاملإلى هذا الملف.

عادةً ما يشغل وصف بيان Declare مساحة كبيرة جدًا ولا يتناسب مع سطر واحد في نافذة التعليمات البرمجية. لذلك ، نوصيك باتباع مخطط محدد لفصل الأسطر عند كتابة التطبيقات ، على سبيل المثال:

قم بتعريف الوظيفة GetTempPath _ Lib "kernel32" Alias ​​"GetTempPathA" _ (ByVal nBufferLength طويل ، _ ByVal lpBuffer كسلسلة) بطول

في هذه الحالة ، يتم فصل جميع العناصر الرئيسية للوصف إلى سطور مختلفة وبالتالي تتم قراءتها جيدًا.

النصيحة 2: كن حذرًا بشكل خاص عند العمل مع وظائف DLL

يؤدي استخدام Win API ووظائف DLL المختلفة إلى توسيع وظائف VB بشكل كبير وغالبًا ما يؤدي إلى تحسين أداء البرامج. ومع ذلك ، فإن المردود لهذا هو خطر تقليل موثوقية التطبيق ، خاصة في عملية تصحيحه.

واحدة من أهم مزايا بيئة VB هي موثوقية عملية تطوير البرنامج: العمل تحت سيطرة المترجم الفوري ، كود البرمجةنظريا لا يمكن كسر عمل ويندوزو VB نفسها. قد لا يكون المبرمج منتبهًا جدًا لصحة تمرير المعلمات إلى الوظائف المسماة - أخطاء مماثلةيمكن للمترجم نفسه اكتشافه بسهولة ، إما أثناء ترجمة الكود أو أثناء تنفيذه. في أكثر الحالات غير السارة ، سيتم مقاطعة وضع المعالجة ببساطة ، مع الإشارة إلى مكان حدوث الخطأ وسبب حدوثه.

يؤدي استخدام وظائف Windows API أو مكتبات DLL الأخرى مباشرةً إلى إزالة هذا التحكم في نقل البيانات وتنفيذ التعليمات البرمجية خارج بيئة VB. لذلك ، يمكن أن يؤدي الخطأ في الوصول إلى الوظائف الخارجية إلى عدم تشغيل كل من VB ونظام التشغيل. هذا صحيح بشكل خاص في مرحلة تطوير البرنامج ، عندما يكون وجود الأخطاء أمرًا طبيعيًا تمامًا. وبالتالي ، من خلال تطبيق الاحتمالات الأوسع لوظائف الطبقة الأساسية للنظام ، يتحمل المبرمج مسؤولية صحة تطبيقهم.

تتفاقم المشكلة بسبب حقيقة أن لغات البرمجة المختلفة تستخدم طرقًا مختلفة لتمرير المعلمات بين الإجراءات. (أكثر دقة، طرق مختلفةالتمريرات هي الخيار الافتراضي لأن العديد من اللغات قد تدعم طرقًا متعددة.) يتم تنفيذ واجهات برمجة تطبيقات Win في C / C ++ وتستخدم معايير تمرير معلمات النظام ، والتي تختلف عن استخدام VB.

في هذا الصدد ، تجدر الإشارة إلى أن ظهور نظائر وظائف API المضمنة في VB له ما يبرره بدقة من خلال تكييف الأخير مع بناء جملة VB وتنفيذ آلية التحكم في تبادل البيانات المقابلة. دعونا نلاحظ أيضًا أنه في مرحلة التصحيح التجريبي للتطبيق ، عند الإنشاء وحدة قابلة للتنفيذمن الأفضل استخدام خيار التحويل البرمجي P-code بدلاً من الكود الأصلي (كود الآلة). في الحالة الأولى ، سيعمل البرنامج تحت سيطرة مترجم - أبطأ من رمز الآلة ، ولكنه أكثر موثوقية من حيث الآثار الخاطئة المحتملة على نظام التشغيل وتوفير وضع أكثر ملاءمة لاكتشاف الأخطاء المحتملة.

النصيحة 3: نصائح Dan Appleman العشر لبرمجة API موثوقة في VB

يتطلب استخدام وظيفة API برمجة أكثر دقة ، باستخدام بعض الأساليب غير المألوفة لإجراءات الاستدعاء (مقارنة بـ VB). سنواصل معالجة هذه القضايا في ما يلي. والآن إليك ملخص لنصيحة Dan Appleman حول هذا الموضوع (ظهرت نسختهم الأولى في عام 1993) ، مع بعض الإضافات والتعليقات.

1. تذكر ByVal.معظم خطأ عام، الذي يتم إجراؤه عند الوصول إلى وظائف API و DLL ، هو الاستخدام غير الصحيح لـ كلمة رئيسية ByVal: إما أن ينسوا وضعه ، أو على العكس من ذلك ، وضعه عندما لا يكون ضروريًا.

توضح هذه الأمثلة تأثير بيان ByVal على تمرير المعلمة

نوع المعلمة مع ByVal بدون ByVal
عدد صحيح يتم دفع عدد صحيح 16 بت على المكدس. يتم دفع العنوان 32 بت لعدد صحيح 16 بت إلى المكدس.
طويل يتم دفع عدد صحيح 32 بت إلى المكدس. يتم دفع العنوان 32 بت لعدد صحيح 32 بت إلى المكدس.
خيط يتم تحويل السلسلة إلى التنسيق المستخدم في C (البيانات و بايت فارغ منتهي). عنوان 32 بت خط جديددفعت على المكدس يتم دفع واصف السلسلة VB على المكدس. (لا يتم استخدام هذه المقابض أبدًا بواسطة واجهة برمجة تطبيقات Windows نفسها ولا يتم التعرف عليها إلا في مكتبات DLL المُنفذة خصيصًا لـ VB.)

وتجدر الإشارة هنا إلى أن تمرير المعلمات في أي نظام البرمجة، بما في ذلك VB ، يتم تنفيذه بطريقتين رئيسيتين: عن طريق المرجع (ByRef) أو بالقيمة (ByVal). في الحالة الأولى ، يتم تمرير عنوان المتغير (يتم استخدام هذا الخيار افتراضيًا في VB) ، في الحالة الثانية - قيمته. يكمن الاختلاف الأساسي في حقيقة أنه بمساعدة مرجع ، يتم إرجاع القيمة المتغيرة للمعامل الذي تم تمريره إلى برنامج الاستدعاء.

لفهم ذلك ، قم بإجراء تجربة باستخدام البرامج التالية:

Dim v As Integer v = 2 Call MyProc (v) MsgBox "v =" & v Sub MyProc (v As Integer) v = v + 1 End Sub

عند تشغيل هذا المثال ، ستتلقى رسالة بقيمة المتغير تساوي 3. والحقيقة هي أنه في هذه الحالة ، يتم تمرير عنوان المتغير v ، الذي تم إنشاؤه فعليًا في برنامج الاستدعاء ، إلى روتين MyProc. الآن قم بتغيير وصف الإجراء إلى

Sub MyProc (ByVal v As Integer)

نتيجة لذلك ، عند تشغيل الاختبار ، ستحصل على v = 2 ، لأنه يتم تمرير القيمة الأولية للمتغير فقط إلى الإجراء - لا يتم إرجاع نتيجة العمليات التي أجريت عليه إلى برنامج الاستدعاء. يمكنك أيضًا تغيير وضع pass-by-value باستخدام عبارة Call كما يلي:

Sub MyProc (v As Integer) ... استدعاء MyProc ((v)) '(v) - تشير الأقواس إلى وضع _ pass-by-value.

ومع ذلك ، عند الإشارة إلى إجراءات VB الداخلية ، يُحظر استخدام الكلمة الأساسية ByVal في بيان المكالمة - يتم استخدام الأقواس بدلاً من ذلك. هذا له تفسيره الخاص.

في الحالة الكلاسيكية (C ، Fortran ، Pascal) ، يعتمد الاختلاف بين وضعي ByRef و ByVal على ما يتم وضعه بالضبط في مكدس تبادل البيانات - عنوان المتغير أو قيمته. يستخدم Basic تاريخيًا متغيرًا من محاكاة برنامج ByVal - يكون العنوان دائمًا في المكدس ، ولكن فقط عند التمرير بالقيمة يكون متغيرًا مؤقتًا تم إنشاؤه لهذا الغرض. للتمييز بين هذين الخيارين (الكلاسيكي والأساسي) ، يتم استخدام طرق مختلفة لوصف وضع ByVal. لاحظ أن محاكاة وضع ByVal في VB يوفر موثوقية أعلى للبرنامج: من خلال الخلط بين شكل الاستدعاء ، يخاطر المبرمج فقط بإعادة القيمة المصححة للمتغير (أو عدم إرجاعها) إلى برنامج الاستدعاء. ومع ذلك ، في الإصدار "الكلاسيكي" ، يمكن أن يؤدي هذا الالتباس إلى خطأ فادح عند تنفيذ الإجراء (على سبيل المثال ، عند استخدام قيمة متغيرة تساوي ، على سبيل المثال ، الصفر بدلاً من عنوان الذاكرة).

يتم تنفيذ وظائف DLL وفقًا للمبادئ "الكلاسيكية" ، وبالتالي تتطلب وصفًا إلزاميًا لكيفية تبادل البيانات مع كل من الوسيطات. هذا هو الغرض من إعلانات الوظائف من خلال وصف Declare (بشكل أكثر دقة ، قائمة الوسائط التي تم تمريرها). الطريقة الأكثر شيوعًا لتمرير المعلمات إلى Windows API أو وظيفة DLL هي استخدام الكلمة الأساسية ByVal. علاوة على ذلك ، يمكن تعيينه في كل من بيان Declare ، ومباشرة عند استدعاء الوظيفة.

من السهل التنبؤ بنتائج تمرير المعلمة غير الصحيحة. إذا تلقيت عنوانًا غير صالح بشكل واضح ، فستتلقى رسالة GPF (خطأ حماية عام). إذا تلقت الوظيفة قيمة تطابق عنوانًا صالحًا ، فستقوم وظيفة API بالزحف إلى منطقة شخص آخر (على سبيل المثال ، إلى Windows kernel) مع كل العواقب الكارثية المترتبة على ذلك.

2. تحقق من نوع المعلمات التي تم تمريرها.نفس القدر من الأهمية هو العدد الصحيح ونوع المعلمات التي تم تمريرها. يجب أن تتطابق الوسائط المُعرَّفة في Declare مع المعلمات المتوقعة في دالة API. ترتبط أكثر حالات الخطأ شيوعًا في تمرير المعلمات بالاختلاف بين السلسلة النصية ذات الطول الفارغ والسلسلة ذات الطول الصفري - تذكر أنهما ليسا نفس الشيء.

3. تحقق من نوع الإرجاع.

VB متسامح جدًا مع عدم تطابق نوع إرجاع الوظيفة ، حيث يتم إرجاع القيم الرقمية عادةً عبر السجلات بدلاً من المكدس. ستساعد القواعد التالية في تحديد القيمة الصحيحة التي تُرجعها دالة API:

  • يجب التصريح عن دالة DLL التي لا تُرجع قيمة (مشابهة للفراغ في 'C') على أنها VB Sub.
  • يمكن تعريف دالة API التي تقوم بإرجاع قيمة عدد صحيح (عدد صحيح أو طويل) على أنها إما دالة فرعية أو دالة تقوم بإرجاع قيمة من النوع المناسب.
  • لا تقوم أي من وظائف API بإرجاع أرقام الفاصلة العائمة ، ولكن قد تقوم بعض مكتبات DLL بإرجاع مثل هذا النوع من البيانات.

4. استخدم بنية "As Any" بعناية فائقة.العديد من وظائف Windows API لديها القدرة على قبول المعلمات أنواع مختلفةواستخدم الاستدعاء باستخدام بنية As Any (يتم تنفيذ تفسير النوع اعتمادًا على قيمة المعلمات الأخرى التي تم تمريرها).

قد يكون الحل الجيد في هذه الحالة هو استخدام عدة أسماء مستعارة للوظائف (الاسم المستعار) مع إنشاء تعريفين أو أكثر لنفس الوظيفة ، ويحدد كل إعلان معلمات من نوع معين.

5. لا تنسَ تهيئة السلاسل.هناك العديد من الوظائف في Win API والتي تقوم بإرجاع المعلومات عن طريق تحميل البيانات في مخازن السلسلة التي تم تمريرها كمعامل. في برنامجك ، يمكنك أن تفعل كل شيء بشكل صحيح: لا تنسَ ByVal ، قم بتمرير المعلمات بشكل صحيح إلى الوظيفة. لكن يتعذر على Windows التحقق من حجم الذاكرة المخصصة للسلسلة. يجب أن يكون الصف كبيرًا بما يكفي لاستيعاب جميع البيانات التي يمكن وضعها فيه. تقع على عاتق مبرمج VB مسؤولية حجز مخزن مؤقت بالحجم الصحيح.

لاحظ أنه في Windows 32 بت ، يتم تحويل السلاسل من Unicode (ترميز مزدوج البايت) إلى ANSI (بايت واحد) والعكس صحيح ، مع مراعاة الإعدادات الوطنية للنظام. لذلك ، لحجز المخازن المؤقتة ، يكون في بعض الأحيان أكثر ملاءمة لاستخدام صفائف البايت بدلاً من متغيرات السلسلة. (سيتم مناقشة المزيد حول هذا أدناه.)

في أغلب الأحيان ، تسمح لك وظائف Win API بتعريف ملفات أكبر مقاسحاجز. على وجه الخصوص ، يتطلب هذا أحيانًا استدعاء وظيفة واجهة برمجة تطبيقات أخرى من شأنها "المطالبة" بحجم الكتلة. على سبيل المثال ، يسمح لك GetWindowTextLength بتحديد حجم السلسلة المطلوبة لتتوافق مع عنوان الإطار الذي تم إرجاعه بواسطة دالة GetWindowText. في هذه الحالة ، يضمن Windows عدم الخروج عن الحدود.

6. تأكد من استخدام Option Explicit.

7. تحقق بعناية من قيم المعلمات وقيم الإرجاع.يمتلك VB فرص جيدةلفحص النوع. هذا يعني أنه عند محاولة تمرير معلمة غير صالحة إلى وظيفة VB ، فإن أسوأ شيء يمكن أن يحدث هو أن تتلقى رسالة خطأ من VB. لكن هذه الآلية، للأسف ، لا يعمل عند الوصول خصائص الويندوز API.

يحتوي Windows 9x على نظام محسّن لفحص المعلمات لمعظم وظائف API. لذلك ، فإن وجود خطأ في البيانات عادة لا يتسبب في حدوث خطأ فادح ، ولكن ليس من السهل تحديد سبب ذلك.

هنا يمكننا أن ننصحك باستخدام عدة طرق لتصحيح هذا النوع من الأخطاء:

  • استخدم التصحيح خطوة بخطوة أو الأمر Debug.Print لفحص كل استدعاء دالة API مشبوهة. تحقق من نتائج هذه المكالمات للتأكد من أن كل شيء على ما يرام وتم إنهاء الوظيفة بأمان ؛
  • استخدام مصحح أخطاء Windows مثل CodeView و Debugger نسخة ويندوز(متوفر في Windows SDK). يمكن لهذه الأدوات اكتشاف خطأ المعلمة وتحديد وظيفة API التي تسبب الخطأ على الأقل ؛
  • استخدم أدوات خارجية إضافية للتحقق من أنواع المعلمات وصحة قيمها. لا يمكن لمثل هذه الأدوات العثور على أخطاء المعلمات فحسب ، بل يمكنها أيضًا الإشارة إلى سطر رمز VB حيث حدث الخطأ.

بالإضافة إلى ذلك ، من الضروري التحقق من نتيجة تنفيذ وظيفة API.

8. تذكر أن الأعداد الصحيحة في VB و Windows ليست هي نفسها.بادئ ذي بدء ، يجب أن تضع في اعتبارك أن المصطلح "عدد صحيح" في VB يشير إلى رقم 16 بت ، في وثائق Win 32 - رقم 32 بت. ثانيًا ، الأعداد الصحيحة (عدد صحيح وطويل) في VB هي قيم موقعة (أي ، يتم استخدام بت واحد كإشارة ، والباقي يستخدم باعتباره الجزء العشري للرقم) ، في Windows يتم استخدام الأرقام غير السالبة فقط. يجب وضع هذا الظرف في الاعتبار عند تكوين المعلمة التي تم تمريرها باستخدام العمليات الحسابية (على سبيل المثال ، احسب العنوان عن طريق جمع بعض الأساس والإزاحة). وظائف VB الحسابية القياسية ليست مناسبة لهذا الغرض. كيف نكون في هذه الحالة سنتحدث بشكل منفصل.

9. انتبه جيدًا لأسماء الوظائف.على عكس Win16 ، فإن أسماء جميع وظائف Win32 API حساسة للاستخدام الدقيق للأحرف الصغيرة والكبيرة (لم يكن هذا هو الحال في Win16). إذا كنت تستخدم حرفًا صغيرًا بدلاً من حرف كبير في مكان ما ، أو العكس ، إذن الوظيفة المطلوبةلن يتم العثور عليها. اتبع أيضا الاستخدام الصحيحاللاحقة A أو W في الدوال التي تستخدم معلمات السلسلة. (لمزيد من المعلومات حول هذا ، انظر أدناه).

10. احفظ عملك في كثير من الأحيان.يمكن أن تؤدي الأخطاء المتعلقة بالاستخدام غير الصحيح لـ DLL و Win API إلى تعطل بيئة VB ، وربما نظام التشغيل بأكمله. يجب عليك التأكد من حفظ الرمز الذي تكتبه قبل التشغيل التجريبي. أبسطها هو ضبط وحدات المشروع على التسجيل التلقائي قبل تشغيل المشروع في VB.

بعد قراءة النصيحة السابقة ، قد تعتقد أن استخدام وظائف Win API هو عمل محفوف بالمخاطر. هذا صحيح إلى حد ما ، ولكن فقط بالمقارنة مع البرمجة الآمنة التي يوفرها VB نفسها. ولكن مع تطبيقهم الماهر ومعرفتهم بالمخاطر المحتملة ، فإن هذا الخطر ضئيل للغاية. بالإضافة إلى ذلك ، غالبًا ما يكون من المستحيل التخلي تمامًا عن استخدام Win API - ستظل مطلوبة لأي تطوير جدي.

بالإضافة إلى ذلك ، ذكرنا سابقًا "المزالق" لفئة واسعة من DLL. في حالة Win API ، يكون كل شيء أبسط بكثير ، نظرًا لأن شكل استدعاء هذه الوظائف موحد بوضوح هنا. عند القيام بذلك ، يجب مراعاة النقاط الرئيسية التالية:

  1. وظائف Win32 API هي وظائف بالضبط ، أي إجراءات من النوع Function (كان هناك العديد من الإجراءات الفرعية في Win16 API). هذه كلها وظائف من النوع طويل ، لذلك تتم كتابة أوصافها على النحو التالي: قم بتعريف اسم الوظيفة ... طالما تم تعريف نوع الوظيفة _ بشكل صريح

    قم بتعريف اسم الوظيفة & "نوع الوظيفة _ معرّف لاحقة

    يبدو استدعاء وظيفة API كما يلي:

النتيجة & = ApiName & ([ قائمة الحجج]
  1. غالبًا ما تكون القيمة المرجعة للدالة هي رمز الخروج من العملية. علاوة على ذلك ، فإن القيمة غير الصفرية في هذه الحالة تعني الإكمال الطبيعي ، صفر - خطأ. يمكنك عادةً (ولكن ليس دائمًا) التحقق من طبيعة الخطأ عن طريق استدعاء دالة GetLastError. وصف هذه الوظيفة كما يلي: Declare Function GetLastError & Lib "kernel32" ()

    انتباه!عند العمل في VB ، من الأفضل استخدام خاصية LastDLLError للكائن Err للحصول على قيمة رمز الخطأ المكرر ، لأن VB يعيد أحيانًا تعيين وظيفة GetLastError بين استدعاء واجهة برمجة التطبيقات والاستمرار في تنفيذ البرنامج.

    يمكنك تفسير الكود الذي تم إرجاعه بواسطة GelLastError باستخدام الثوابت المكتوبة في ملف API32.TXT ، مع بدء الأسماء باللاحقة ERROR_.

    معظم أخطاء نموذجيةلديك الرموز التالية:

    • ERROR_INVALID_HANDLE = 6 & - معالج غير صالح
    • ERROR_CALL_NOT_IMPLEMENTED = 120 & - استدعاء في Windows 9x وظيفة متاحة فقط لـ Windows NT
    • ERROR_INVALID_PARAMETER = 87 & - قيمة معلمة غير صالحة

    ومع ذلك ، فإن العديد من الدالات ترجع قيمة بعض المعلمات المطلوبة (على سبيل المثال ، يُرجع OpenFile قيمة واصف الملف). في مثل هذه الحالات ، يتم تعريف الخطأ من خلال بعض قيم العائد والقيمة الخاصة الأخرى ، الأكثر شيوعًا 0 أو -1.

  2. تستخدم واجهات برمجة تطبيقات Win32 طرقًا ثابتة بدقة لتمرير أبسط أنواع البيانات. أ) ByVal ... طالما

    المتغيرات الطويلة تتعامل مع 80٪ على الأقل من الوسيطة التي تمر. لاحظ أن الحجة دائماًمتبوعة بالكلمة الأساسية ByVal ، والتي تعني ، من بين أشياء أخرى ، أنه يتم تنفيذ نقل البيانات في اتجاه واحد - من برنامج VB إلى وظيفة API.

    ب) ByVal ... كسلسلة

    هذا النوع من نقل البيانات شائع أيضًا ، ومع وجود حجة أيضًا دائماًيتم تطبيق ByVal. عندما يتم استدعاء وظيفة API ، يتم كتابة عنوان السلسلة على المكدس ، لذلك في هذه الحالة ، يكون تبادل البيانات ثنائي الاتجاه ممكنًا. هناك العديد من المخاطر التي يجب أن تكون على دراية بها عند العمل بالسلاسل.

    الأول هو أن الذاكرة محجوزة لسلسلة في برنامج الاستدعاء ، لذلك إذا كانت وظيفة API ستملأ السلاسل ، فقبل استدعائها ، تحتاج إلى إنشاء سلسلة بالحجم المطلوب. على سبيل المثال ، ترجع الدالة GetWindowsDirectory المسار إلى دليل Windows ، والذي يجب ألا يزيد بحكم التعريف عن 144 حرفًا. وفقًا لذلك ، يجب أن تبدو الاستدعاء لهذه الوظيفة كما يلي:

    WinPath $ = Space $ (144) ‘سلسلة حجز في _ 144 حرفًا.

    المشكلة الثانية هي أنه عندما يتم استدعاء وظيفة API ، يتم تحويل السلسلة المصدر إلى تمثيل داخلي لها ، والعكس صحيح عند خروج الوظيفة. إذا كانت هذه العملية في وقت Win16 تتكون فقط من إضافة بايت فارغ في نهاية السلسلة ، فعند ظهور Win32 ، تمت إضافة تحويل Unicode المشفر ثنائي البايت إلى ANSI والعكس إلى ذلك. (تمت مناقشة هذا بالتفصيل في مقالة "ميزات العمل مع متغيرات السلسلة في VB" ، ComputerPress 10'99 و 01'2000). في الوقت الحالي ، لاحظ فقط أنه باستخدام ByVal ... كبنية String ، يمكنك فقط تبادل السلاسل مع بيانات الأحرف.

    ج) ... مثل أي

    هذا يعني أنه سيتم دفع بعض عناوين ذاكرة التخزين المؤقت إلى المكدس ، وسيتم تفسير محتوياتها بواسطة وظيفة API ، على سبيل المثال ، اعتمادًا على قيمة الوسائط الأخرى. ومع ذلك ، لا يمكن استخدام أي شيء إلا في بيان Declare - يجب تعريف متغير معين كوسيطة عند إجراء استدعاء محدد للدالة.

    D) ... باسم UserDefinedType

    غالبًا ما يتم استخدام مثل هذا البناء عندما يكون من الضروري تبادل البيانات (بشكل عام في كلا الاتجاهين) باستخدام بعض الهياكل. هذا البناء هو في الواقع نوع من التنفيذ الملموس لنموذج As Any Transfer ، إنه في هذه الحالة يتم تعيين الوظيفة على هيكل ثابت.

    يتم تحديد شكل بنية البيانات من خلال وظيفة API معينة ، وتقع على عاتق المبرمج مسؤولية وصفها بشكل صحيح وحجزها في برنامج الاستدعاء. مثل هذا التصميم دائماًمستخدم بدونكلمات ByVal ، أي في هذه الحالة ، يتم تنفيذ التمرير حسب المرجع - تتم كتابة عنوان المتغير في المكدس.

مثال على استدعاء دالة API

دعونا نوضح ما سبق بمثال على استخدام اثنين ميزات مفيدةالعمل مع الملفات - lopen and lread والتي توصف كالتالي:

قم بتعريف الوظيفة lread Lib "kernel32" _ Alias ​​"_lread" (_ ByVal lpFileName كسلسلة ، _ ByVal wReadWrite As Long) As Long Declare Function lread Lib "kernel32" _ Alias ​​"_lread" (_ ByVal h ملف طويل ، lpBuffer مثل أي ، _ ByVal wBytes طالما) طويلة

في VB ، نظرائهم - في هذه الحالة بالضبط - هم عاملي Open and Get (للوضع الثنائي). دعنا ننتبه على الفور إلى استخدام الكلمة الأساسية Alias ​​في إعلان الوظيفة - هذه هي الحالة فقط عندما لا يمكنك الاستغناء عنها. تبدأ أسماء الوظائف الحقيقية في المكتبة بشرطة سفلية (نمط C نموذجي) ، وهو غير مسموح به في VB.

قد تبدو عملية فتح الملف كما يلي:

Const INVALID_HANDLE_VALUE = -1 'غير صالح _ قيمة المقبض lpFileName $ = "D: \ calc.bas" "اسم الملف wReadWrite & = 2' وضع القراءة والكتابة hFile & = lopen (lpFileName $، wReadWrite &) _ 'عرّف معالجة الملف إذا كانت hFile & = INVALID_HANDLE_VALUE ثم _ 'خطأ في فتح الملف' تحديد رمز الخطأ CodeError & = Err.LastDllError 'CodeError & = GetLastError _' هذا البناء لا يعمل إنهاء إذا

هنا تحتاج إلى الانتباه إلى نقطتين:

  • كقيمة للدالة ، نحصل على قيمة واصف الملف. خطأ يتوافق مع قيمة -1 ؛
  • فقط في هذه الحالة ، لا يعمل استدعاء وظيفة GetLastError - للحصول على قيمة الخطأ المكررة ، لجأنا إلى كائن Err (تحدثنا عن احتمال حدوث مثل هذا الموقف أعلاه).

يمكنك بعد ذلك قراءة محتويات الملف ، ولكن هذا يفترض أن المبرمج يجب أن يكون لديه بعض الفهم لهيكله (تمامًا كما يحدث عند العمل مع ملفات ثنائية عشوائية). في هذه الحالة ، قد يبدو استدعاء وظيفة lread كما يلي:

Dim MyVar As Single wBytes = lread (hFile &، MyVar، Len (MyVar) 'قراءة رقم حقيقي ، 4 بايت wBytes هو عدد البيانات التي تمت قراءتها بالفعل ،' -1 خطأ ... اكتب MyStruct x As Single i As نوع نهاية صحيح Dim MyVar As MyStruct wBytes = lread (hFile &، MyVar، Len (MyVar)) 'قراءة بنية البيانات ، 6 بايت

لاحظ مرة أخرى أن الوسيطة الثانية للدالة يتم تمريرها من خلال المرجع ، والباقي حسب القيمة.

Dim MyVar As String MyVar = Space $ (10) 'متغير احتياطي لـ 10 أحرف wBytes = lread (hFile &، ByVal MyVar، Len (MyVar))' قراءة سلسلة أحرف ، 10 أحرف

هنا يمكنك أن ترى اختلافًا مهمًا عن المثال السابق - متغير السلسلة يكون بالضرورة مصحوبًا بالكلمة الأساسية ByVal.

يتم تنفيذ قراءة محتويات ملف في مصفوفة (للتبسيط ، سنستخدم مصفوفة بايت أحادية البعد) على النحو التالي:

Dim MyArray (1 إلى 10) كـ Byte wBytes = lread (hFile &، MyArray (1)، _ Len (MyArray (1)) * 10) "قراءة 10 عناصر مصفوفة

من خلال تحديد العنصر الأول من المصفوفة كوسيطة ، نقوم بتمرير عنوان بداية منطقة الذاكرة المحجوزة للمصفوفة. من الواضح أن أي جزء من المصفوفة يمكن ملؤه بهذه الطريقة:

WBytes = lread (hFile &، MyArray (4)، _ Len (MyArray (1)) * 5) 'قراءة عناصر المصفوفة من الرابع إلى الثامن

نصيحة 5: استخدم الاسم المستعار لعمليات الإرسالوالمعلمات كأي

هنا ، بناءً على المثال السابق ، سنكشف عن جوهر النصيحة الرابعة لـ Dan Appleman.

عند العمل مع وظيفة lread ، يجب أن تتذكر أنه عند الوصول إليها باستخدام متغير سلسلة ، يجب عليك استخدام الكلمة الأساسية ByVal (وإلا فلا يمكن تجنب الرسالة المتعلقة بعملية غير قانونية). لكي تكون آمنًا ، يمكنك عمل وصف خاص إضافي لنفس الوظيفة للعمل فقط مع متغيرات السلسلة:

قم بتعريف الوظيفة lreadString Lib "kernel32" _ Alias ​​"_lread" (_ ByVal h ملف طويل ، ByVal lpBuffer كسلسلة ، _ ByVal wBytes بطول)

عند العمل بهذا الوصف ، لم تعد بحاجة إلى تحديد ByVal عند الوصول إلى:

WBytes = lreadString (hFile &، MyVarString، _ Len (MyVarString)) '

يبدو أن بناء جملة عامل التشغيل Declare يسمح لك بعمل مثل هذا التصريح الخاص لمصفوفة:

قم بتعريف الوظيفة lreadString Lib "kernel32" الاسم المستعار "_lread" (_ ByVal h ملف طويل ، lpBuffer () بالبايت ، _ ByVal wBytes بطول) طويل

ومع ذلك ، فإن النداء

WBytes = lreadArray (hFile &، MyArray ()، 10)

يؤدي حتما إلى خطأ فادح في البرنامج.

هذا استمرار للمحادثة حول خصائص معالجة متغيرات السلسلة في Visual Basic: يستخدم VB ترميز Unicode ثنائي البايت ، ويستخدم Win API ترميز ANSI أحادي البايت (علاوة على ذلك ، مع التنسيق المعتمد في C ، مع بايت فارغ في نهايةالمطاف). وفقًا لذلك ، عند استخدام متغيرات السلسلة كوسيطة ، يتم دائمًا إجراء التحويل من Unicode إلى ANSI تلقائيًا عند استدعاء دالة API (بتعبير أدق ، دالة DLL) و التحويل العكسيعند عودته.

الاستنتاج من هذا بسيط: يمكن استخدام متغيرات السلسلة لتبادل بيانات الأحرف ، لكن لا يمكن استخدامها لتبادل المعلومات الثنائية العشوائية (كما كان الحال مع إصدارات 16 بت من VB). في الحالة الأخيرة ، من الأفضل استخدام مصفوفة بايت أحادية البعد.

كما تعلم ، يمكن استخدام نوع String لوصف بنية مخصصة. في هذا الصدد ، يجب تذكر ما يلي:

  • يُمنع منعًا باتًا استخدام البنية التالية للوصول إلى Win API: اكتب MyStruct x As Single s As String ‘سلسلة متغيرة الطول End Type

    في حالة السلسلة ذات الطول المتغير ، يتم تمرير واصف السلسلة كجزء من البنية ، مع كل النتائج المترتبة على ذلك في شكل خطأ في تنفيذ البرنامج.

  • يمكنك استخدام سلسلة ذات طول ثابت كعنصر بنية: اكتب MyStruct x As Single s As String * 8 ‘سلسلة ذات طول ثابت نوع النهاية

في هذه الحالة ، يتم إجراء تحويل الترميز المقابل.

والملاحظة الأخيرة: لا يمكنك استخدام مصفوفة من متغيرات السلسلة (الطول الثابت والمتغير) عند الوصول إلى دالة API في أي حال. وإلا فإن ظهور "عملية غير قانونية" سيكون مضمونًا.

من المحتمل أن يكون لديك موقف تحتاج فيه إلى كتابة وظائف DLL الخاصة بك. ستظهر الحاجة إلى ذلك حتماً إذا كنت تستخدم تقنية البرمجة المختلطة - استخدام لغتين أو أكثر من لغات البرمجة لتنفيذ تطبيق واحد.

في هذا الصدد ، نلاحظ أن البرمجة المختلطة شائعة جدًا لتنفيذ تطبيق معقد إلى حد ما. في الواقع ، كل لغة (بتعبير أدق ، نظام برمجة قائم على اللغة) لها نقاط قوتها و الجوانب الضعيفةلذلك فمن المنطقي تمامًا استخدام مزايا الأدوات المختلفة لحل المشكلات المختلفة. على سبيل المثال ، VB - لإنشاء واجهة مستخدم ، C - للوصول الفعال إلى موارد النظام ، Fortran - لتنفيذ الخوارزميات الرقمية.

رأي المؤلف كالتالي: أي برمجة جادة تتطلب من المطور امتلاك أداتين على الأقل. بالطبع ، في ظل ظروف التقسيم الواضح للعمل اليوم ، من الصعب جدًا أن تكون خبيرًا ممتازًا حتى في نظامين ، لذا فإن مخطط "اللغات الرئيسية والمساعدة" أكثر منطقية. الفكرة هنا هي أنه حتى القليل من المعرفة باللغة "المساعدة" (كتابة إجراءات بسيطة إلى حد ما) يمكن أن تحسن بشكل كبير من كفاءة اللغة "الرئيسية". لاحظ أن معرفة VB ، على الأقل كمساعد ، هي اليوم مطلب إلزامي تقريبًا للمبرمج المحترف. بالمناسبة ، في أيام DOS لأي مبرمج ، بما في ذلك Basic ، كان من المرغوب فيه للغاية معرفة أساسيات المجمع.

بطريقة أو بأخرى ، ولكن حتى في ظروف العمل الجماعي ، عندما يشارك كل مبرمج في عمله الخاص ، يجب أن يكون لدى جميع المشاركين في المشروع فكرة عن ميزات الواجهة الإجرائية بلغات مختلفة. وللتعرف على أن العديد من أنظمة البرمجة (بما في ذلك VB) ، بالإضافة إلى الواجهة الافتراضية ، تتيح لك استخدام طرق موسعة أخرى لإجراءات الاتصال ، مما يجعل من الممكن تكييف الواجهة مع لغة أخرى.

عند دراسة الواجهة بين الإجراءات ، يجب الانتباه إلى "المزالق" المحتملة التالية:

  • قد تستخدم اللغات المختلفة اصطلاحات مختلفة لكتابة المعرفات. على سبيل المثال ، من الشائع استخدام شرطة سفلية في بداية اسم الإجراء ، وهو أمر غير مسموح به في VB. يتم حل هذه المشكلة بسهولة باستخدام الكلمة الأساسية Alias ​​في بيان Declare (انظر النصيحة 2-3 على سبيل المثال).
  • يمكن استخدام تسلسل مختلف من الكتابة التي تم تمريرها إلى المكدس. على سبيل المثال ، في أيام DOS (لأكون صادقًا - لا أعرف كيف يبدو الآن بيئة Windows) ، كتب C الحجج من نهاية القائمة ، لغات أخرى (Fortran ، Pascal ، Basic) - من البداية.
  • بشكل افتراضي ، يتم استخدام مبادئ مختلفة لتمرير المعلمات - حسب المرجع أو حسب القيمة.
  • مبادئ مختلفة لتخزين متغيرات السلسلة. على سبيل المثال ، في لغة C (وكذلك في Fortran و Pascal) ، يتم تحديد طول السلسلة بواسطة بايت فارغ في نهايتها ، بينما في Basic يتم كتابة الطول بشكل صريح في واصف السلسلة. بالطبع ، يجب على المرء أن يضع في اعتباره إمكانية استخدامه ترميزات مختلفةالشخصيات.
  • عند نقل المصفوفات متعددة الأبعاد ، يجب أن نتذكر أن هناك خيارات مختلفة لتحويل الهياكل متعددة الأبعاد إلى هياكل أحادية البعد (بدءًا من الفهرس الأول أو من الأخير ، بالنسبة إلى المصفوفات ثنائية الأبعاد - "حسب الصفوف" أو "حسب الأعمدة ").

مع وضع ذلك في الاعتبار ، يمكن صياغة التوصيات التالية:

  • استخدم أبسط الطرق التي أثبتت جدواها لتمرير الوسائط إلى دوال DLL. المعايير المعتمدة لـ Win API مناسبة تمامًا كنموذج.
  • لا تمرر أبدًا مصفوفات من متغيرات السلسلة.
  • كن حذرًا جدًا بشأن تمرير متغيرات السلسلة البسيطة والمصفوفات متعددة الأبعاد.
  • تأكد من التحقق من وظيفة آلية تمرير الوسائط من وإلى الإجراء المطلوب بطريقة خاصة. اكتب اختبارًا مخصصًا للتحقق من نقل البيانات. تحقق بشكل منفصل من تمرير كل وسيطة بشكل صحيح. على سبيل المثال ، إذا كان لديك إجراء به عدة وسيطات ، فتحقق أولاً من صحة تمرير كل معلمة لمتغير باستخدام وسيطة واحدة ، وبعد ذلك فقط - للقائمة بأكملها.

ولكن ماذا لو كانت وظيفة DLL مكتوبة بالفعل ، على سبيل المثال ، في Fortran ، لكن واجهة الإدخال الخاصة بها لا تتناسب جيدًا مع معايير VB أعلاه؟ هناك نوعان من النصائح هنا. أولاً: اكتب دالة اختبار DLL واستخدمها لمحاولة العثور على المكالمة الصحيحة من برنامج VB عن طريق التجربة والخطأ. ثانيًا: كتابة إجراء مهايئ في نفس Fortran من شأنه أن يوفر واجهة بسيطة بين دالة VB و DLL مع تحويل هياكل البيانات البسيطة إلى هياكل معقدة (على سبيل المثال ، تحويل مصفوفة بايت متعددة الأبعاد إلى مصفوفة سلسلة).

لذلك: استخدم وظائف DLL. لكن كن يقظا ...

كمبيوتر برس 9 "2000

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

كما ذكرنا سابقًا ، تعد واجهة برمجة التطبيقات ، أولاً وقبل كل شيء ، واجهة. واجهة تتيح للمطورين استخدام الكتل الجاهزة لإنشاء تطبيق. في حالة التنمية تطبيقات الهاتف الجواليمكن أن تعمل مكتبة للعمل مع "المنزل الذكي" كواجهة برمجة تطبيقات - يتم تنفيذ جميع الفروق الدقيقة في المكتبة وأنت تشير فقط إلى واجهة برمجة التطبيقات هذه في التعليمات البرمجية الخاصة بك.

في حالة تطبيقات الويب ، يمكن لواجهة برمجة التطبيقات إرجاع البيانات بتنسيق غير HTML القياسي ، مما يجعلها ملائمة للاستخدام عند كتابة تطبيقاتك الخاصة. غالبًا ما تعرض واجهات برمجة التطبيقات العامة التابعة لجهات خارجية البيانات بأحد التنسيقين: XML أو JSON. إذا قررت إنشاء واجهة برمجة تطبيقات لتطبيقك ، فتذكر أن JSON أكثر إيجازًا وأسهل في القراءة من XML ، وأن الخدمات التي توفر الوصول إلى البيانات بتنسيق XML تعمل على التخلص التدريجي من الأخير.

API في تطبيقات الويب عن طريق الأمثلة

تطبيق - على سبيل المثال ، Github - له واجهة برمجة تطبيقات خاصة به يمكن للمطورين الآخرين استخدامها. تعتمد طريقة استخدامهم لها على الاحتمالات التي توفرها واجهة برمجة التطبيقات ومدى جودة عمل خيال المطورين. تسمح Github API ، على سبيل المثال ، بالحصول على معلومات حول المستخدم ، وصورته الرمزية ، والقراء ، والمستودعات ، والعديد من المعلومات الأخرى المفيدة والمثيرة للاهتمام.

وبالمثل ، يمكنك إرسال طلب بأي لغة ، بما في ذلك لغة Ruby. سيكون الرد على الطلب مثل هذا:

("تسجيل الدخول": "Freika" ، "id": 3738638 ، "avatar_url": "https://avatars.githubusercontent.com/u/3738638؟v=3"، "gravatar_id": ""، "url": "https://api.github.com/users/Freika"، "html_url": "https://github.com/Freika"، "Followers_url": "https://api.github.com/users/Freika/followers"، "following_url": "https://api.github.com/users/Freika/following(/other_user)"، "gists_url": "https://api.github.com/users/Freika/gists(/gist_id)"، "starred_url": "https://api.github.com/users/Freika/starred(/owner)(/repo)"، "subscriptions_url": "https://api.github.com/users/Freika/subscriptions"، "organization_url": "https://api.github.com/users/Freika/orgs"، "repos_url": "https://api.github.com/users/Freika/repos"، "events_url": "https://api.github.com/users/Freika/events(/privacy)"، "ived_events_url ": "https://api.github.com/users/Freika/received_events"، "type": "User"، "site_admin": false، "name": "Evgeniy"، "company": ""، "blog": "http://frey.su/"، "location": " Barnaul "،" email ":" "،" hireable ": true،" bio ": null،" public_repos ": 39،" public_gists ": 13،" Followers ": 15،" following ": 21،" created_at ": "2013-03-01T13: 48: 52Z"، "updated_at": "2014-12-15T13: 55: 03Z")

كما ترى من الكتلة أعلاه ، تحتوي الاستجابة على تسجيل دخول ، وصورة رمزية ، ورابط إلى الملف الشخصي على الموقع وفي واجهة برمجة التطبيقات ، وحالة المستخدم ، وعدد المستودعات العامة ، وغيرها من المعلومات المفيدة والمثيرة للاهتمام.

API واحد لا يكفي

لا يمثل إنشاء واجهة برمجة تطبيقات كاملة لتطبيقك سوى نصف المعركة. كيف ستصل إلى API؟ كيف يمكن للمستخدمين الوصول إليه؟

أول ما يتبادر إلى الذهن هو السلسلة المعتادة لطلبات HTTP التي يجب الحصول عليها معلومات ضروريةوهذه هي الإجابة الخاطئة. الطريقة الأكثر وضوحًا في هذه الحالة ليست الطريقة الأكثر ملاءمة وبساطة. سيكون من المعقول أكثر إنشاء مكتبة خاصة للعمل مع الواجهة ، والتي ستصف جميع الطرق اللازمة لتلقي المعلومات وإرسالها باستخدام واجهة برمجة التطبيقات.

مرة أخرى ، سنستخدم Github لإعطاء مثال: للعمل مع واجهة برمجة التطبيقات لهذه الخدمة الممتازة (وتوفر واجهتها إمكانيات واسعة) ، تم إنشاء العديد من المكتبات بلغات مختلفة ، على سبيل المثال ، جوهرة Octokit. في وثائق مثل هذه المكتبات (والجوهرة المقدمة كمثال) ، سيتمكن أي مطور مهتم من العثور على جميع الطرق اللازمة لتلقي المعلومات من Github وإرسالها مرة أخرى من خلال واجهة برمجة تطبيقات الخدمة.

وبالتالي ، إذا كنت تقوم بإنشاء واجهة برمجة التطبيقات الخاصة بك ، ففكر في إنشاء مكتبات للعمل معها باللغات الأكثر شيوعًا أيضًا. وكن مستعدًا ، عند مستوى معين من الطلب على تطبيقك ، يمكن لشخص آخر إنشاء مكتبته الخاصة للعمل مع واجهة برمجة التطبيقات الخاصة بك. هذا جيد.

روابط مفيدة

في المقالات اللاحقة ، سنتحدث عن كيفية إنشاء API بشكل صحيح ، وضمان أمانها وتقييد الوصول إلى بعض المعلومات.

صندوق الرمل

مجند 26 نوفمبر 2012 الساعة 01:59 مساءً

ما هو API

  • حجرة القش *

تحيات!
في هذه المقالة ، سنلقي نظرة على ماهية واجهة برمجة التطبيقات وأين وكيف ولأي غرض يتم استخدامها. سننظر أيضًا في كيفية استخدام واجهة برمجة التطبيقات في تطوير الويب الخاص بك وكيف يمكن أن تجعل الحياة أسهل لمبرمج الويب.

فلنبدأ بتعريف. API (واجهة برمجة التطبيقات) هي واجهة برمجة وواجهة لإنشاء التطبيقات. بلغة أكثر قابلية للفهم ، فإن API عبارة عن كود جاهز لتبسيط حياة المبرمج. تم إنشاء واجهة برمجة التطبيقات بحيث يمكن للمبرمج حقًا تسهيل مهمة كتابة هذا التطبيق أو ذاك باستخدام كود جاهز (على سبيل المثال ، الوظائف). jQuery المعروف المكتوب بلغة JavaScript هو أيضًا نوع من واجهة برمجة التطبيقات. إذا أخذنا في الاعتبار هذا المثال بالذات ، فإن jQuery يجعل كتابة التعليمات البرمجية أسهل بكثير. ما يمكن عمله في 30 سطرًا باستخدام أدوات JavaScript المعتادة ، تتم كتابته من خلال jQuery في 5-6. إذا أخذنا في الاعتبار واجهة برمجة التطبيقات بشكل عام ، يمكنك العثور على الكثير من الخدمات التي تمثل حلول التطوير. الأكثر شهرة اليوم هي خدمة code.google.com ، والتي توفر حوالي خمسين واجهة برمجة تطبيقات مختلفة! هذه واجهة لإنشاء تطبيقات Android ، وواجهات برمجة تطبيقات متنوعة للعمل مع AJAX ، وواجهات برمجة تطبيقات متنوعة يمكن تخصيصها بسهولة حسب رغبتك.

بعد كل شيء ، هل من المنطقي كتابة التعليمات البرمجية بيديك؟ لماذا العمل على ما تم إنشاؤه بالفعل؟ هل يعقل رفض الحلول المجانية (وفي الواقع ، المساعدة المجانية) في تطوير الشبكة؟ إذا أجبت بـ "لا" على كل هذه الأسئلة ، فاعتبر أنك تفهم جوهر واجهة برمجة التطبيقات.

لكني أريد أيضًا أن أوضح. يجب على المطورين المبتدئين عدم استخدام الحلول شبه النهائية ، لأنهم لن يتعاملوا مع المهمة الحقيقية في المستقبل. لذلك ، إذا كنت مبرمج ويب مبتدئًا ، فلا تستخدم المنتجات شبه النهائية! تعلم التفكير برأسك ، وبناء خوارزميات مختلفة لفهم جوهر البرمجة. أقول أيضًا ، مخاطبة الجميع بالفعل ، أن واجهة برمجة التطبيقات ليست حلاً جاهزًا ، إنها بيئة وواجهة لإنشاء مشاريعك الخاصة. أنت لا تأكل كرات اللحم المجمدة من المتجر ، أليس كذلك؟ تقلى لهم أولا ، أليس كذلك؟ هذا التشبيه يجسد جوهر واجهة برمجة التطبيقات بوضوح شديد.

بشكل عام ، أخبرت ما هي واجهة برمجة التطبيقات ، وأين وكيف يتم استخدامها ، والأهم من ذلك ، ما الغرض منها. أتمنى لك دراسة ممتعة برمجة الويبوفهم أعماقها المتزايدة باستمرار!

بدون علامات

هذه المقالة لا تخضع للتعليقات ، لأن مؤلفها ليس عضوا كاملا في المجتمع بعد. لن تتمكن من الاتصال بالمؤلف إلا بعد استلامه



تحميل...
قمة