الدوال

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

مَعلمات الدالة

يتم ربط الوسيطات المدرَجة في ملف .hal بأنواع بيانات C++. يتم تمرير الوسيطات التي لا تُعرَّف على أنّها من النوع الأساسي في C++ باستخدام الوسيطة const reference.

لكل دالة HIDL تحتوي على قيمة إرجاع (تتضمّن عبارة generates )، تحتوي قائمة مَعلمات C++ لهذه الدالة على وسيطة إضافية: دالة ردّ اتصال يتمّ استدعاؤها باستخدام قيم الإرجاع لدالة HIDL. هناك استثناء واحد: إذا كانت عبارة generates تحتوي على مَعلمة واحدة ترتبط مباشرةً بعنصر أساسي في C++، يتم استخدام إلغاء ردّ الاتصال (تتم إزالة ردّ الاتصال ويتم عرض القيمة المعروضة من الدالة من خلال عبارة return عادية).

قيم عرض الدوالّ

تعرض الدوالّ التالية قيمًا.

أخطاء النقل ونوع الإرجاع

يمكن أن يؤدي بيان generates إلى ثلاثة أنواع من توقيعات الدوالّ:

  • بالنسبة إلى قيمة عرض واحدة فقط وهي عنصر أساسي في C++، يتم عرض قيمة الإخراج generates حسب القيمة من الدالة في عنصر Return<T>.
  • في الحالات الأكثر تعقيدًا، يتم عرض قيم الإرجاع generates من خلال مَعلمة ردّ الاتصال المقدَّمة مع طلب الدالة نفسها، وتعرِض الدالة Return<void>.
  • في حال عدم توفّر عبارة generates، تعرِض الدالة Return<void>.

قد تواجه طلبات RPC أحيانًا أخطاء في النقل، مثلما يحدث عند تعطُّل الخادم أو عدم كفاية موارد النقل لإكمال الطلب أو عندما لا تسمح المَعلمات التي تم تمريرها بإكمال الطلب (مثل عدم توفُّر دالة رد اتصال مطلوبة). تخزِّن عناصر Return إشارة خطأ النقل بالإضافة إلى قيمة T (باستثناء Return<void>).

بما أنّ الدالتَين من جهة العميل وخادمه تتضمّنان التوقيع نفسه، يجب أن تعرض الدالة من جهة العميل نوع Return حتى إذا كان تنفيذها لا يشير إلى أخطاء النقل. يتم إنشاء كائنات Return<T> باستخدام Return(myTValue) (أو يمكن إنشاؤها بشكل ضمني من mTValue، مثل عبارات return )، ويتم إنشاء كائنات Return<void> باستخدام Void().

تتم تحويل عناصر Return<T> بشكل ضمني إلى قيمة T والعكس. يمكن التحقّق من Return بحثًا عن أخطاء النقل من خلال استدعاء isOk(). هذا التحقّق ليس مطلوبًا، ولكن في حال حدوث خطأ وعدم التحقّق منه بحلول وقت تدمير عنصر Return أو محاولة تحويل قيمة T ، سيتم إنهاء عملية العميل وتسجيل خطأ. إذا كان isOk() يشير إلى خطأ في النقل أو تعذُّر الاتصال بسبب خطأ في منطق رمز المطوّر (مثل تمرير nullptr كسلسلة رسائل برمجية تناشد description() بشكل متزامن)، يمكن استدعاء description() في عنصر Return لمحاولة عرض سلسلة مناسبة للتسجيل. في هذه الحالات، لا تتوفّر طريقة لتحديد مقدار الرمز البرمجي الذي تم تنفيذه على الخادم نتيجةً للاتصال الذي تعذّر إكماله. تتوفّر أيضًا الطريقة isDeadObject(). تشير هذه المحاولة إلى أنّ !isOk() ناتجة عن تعطُّل العنصر البعيد أو عدم توفّره. يشير isDeadObject() دائمًا إلى !isOk().

عرض البيانات حسب القيمة

إذا كان بيان generates يرتبط بعنصر أساسي واحد في C++، لن تكون هناك مَعلمة callback في قائمة المَعلمات. بدلاً من ذلك، يقدّم التنفيذ قيمة الإرجاع T في عنصر Return<T>، والذي يمكن إنشاؤه بشكل ضمني من النوع الأساسي T. على سبيل المثال:

Return<uint32_t> someMethod() {
    uint32_t return_data = ...; // Compute return_data
    return return_data;
};

تتوفّر أيضًا الطريقة Return<*>::withDefault. تقدّم هذه المحاولة قيمة في الحالات التي تكون فيها القيمة المعروضة هي !isOk(). تُصنِّف هذه الطريقة أيضًا تلقائيًا عنصر الإرجاع على أنّه "حسن" حتى لا يتم إنهاء عملية العميل.

العودة باستخدام مَعلمة ردّ الاتصال

يمكن أن تمرِّر وظيفة ردّ الاتصال قيمة الإرجاع لدالة HIDL مرة أخرى إلى المُتصل. النموذج الأولي لوظيفة الاستدعاء هو عنصر std::function يحتوي على مَعلمات (مأخوذة من عبارة generates) تمّ ربطها بأنواع C++. تكون قيمة الإرجاع غير صالحة، لأنّ وظيفة ردّ الاتصال نفسها لا تعرض قيمة.

تكون قيمة الإرجاع لدالة C++ التي تحتوي على مَعلمة ردّ اتصال من النوع Return<void>. لا تتحمّل عملية تنفيذ الخادم سوى مسؤولية تقديم القيمة المعروضة. بما أنّه سبق أن تم نقل قيم الإرجاع باستخدام دالة ردّ الاتصال، تكون مَعلمة النموذج T هي void:

Return<void> someMethod(someMethod_cb _cb);

من خلال تنفيذ C++، يجب أن تعرض عمليات تنفيذ الخادم Void()، وهي دالة ثابتة مضمّنة تعرض Return<void>. مثال على تنفيذ أسلوب خادم عادي باستخدام مَعلمة ردّ اتصال:

Return<void> someMethod(someMethod_cb _cb) {
    // Do some processing, then call callback with return data
    hidl_vec<uint32_t> vec = ...
    _cb(vec);
    return Void();
};

الدوالّ التي لا تعرض قيمًا

توقيع C++ لدالة بدون عبارة generates لن يتضمّن مَعلمة ردّ اتصال في قائمة المَعلمات. سيكون نوع الإرجاع Return<void>..

الدوالّ ذات الاتجاه الواحد

الدوالّ التي تم وضع علامة الكلمة الرئيسية oneway عليها هي دوالّ غير متزامنة (لن يتم حظر البرامج أثناء تنفيذها) ولا تحتوي على قيم مرجعية. لن يتضمّن توقيع C++ لدالة oneway مَعلمة callback في قائمة المَعلمات، وستكون القيمة المعروضة في C++ هي Return<void>.