يتم تعيين الوظائف الموجودة في واجهة HIDL إلى الأساليب الموجودة في إعلان فئة IFoo
C++ الذي تم إنشاؤه تلقائيًا. يبقى اسم كل دالة كما هو في لغة C++؛ تصف الأقسام التالية كيفية ترجمة وسيطات HIDL وقيم الإرجاع إلى C++.
معلمات الوظيفة
يتم تعيين الوسائط المدرجة في ملف .hal
إلى أنواع بيانات C++. يتم تمرير الوسائط التي لا يتم تعيينها إلى نوع C++ بدائي بواسطة مرجع ثابت.
لكل دالة 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()
على كائن Return لإرجاع سلسلة مناسبة للتسجيل. في مثل هذه الحالات، لا توجد طريقة لتحديد مقدار التعليمات البرمجية التي ربما تم تنفيذها على الخادم نتيجة فشل المكالمة. يتم أيضًا توفير الطريقة isDeadObject()
. تشير هذه الطريقة إلى أن !isOk()
يرجع إلى تعطل الكائن البعيد أو أنه لم يعد موجودًا. يشير isDeadObject()
دائمًا إلى !isOk()
.
العودة بالقيمة
إذا كانت عبارة generates
مرتبطة بأساسية C++ واحدة، فلا توجد معلمة رد اتصال في قائمة المعلمات. بدلاً من ذلك، يوفر التنفيذ القيمة المرجعة 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
على معلمة رد اتصال في قائمة المعلمات، وستكون قيمة الإرجاع C++ الخاصة بها هي Return<void>
.