سؤال

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

الأول الذي لا أفهمه هو byte[] localSignature, ، الحجة الثالثة.تنص MSDN على أنها "صفيف من البايتات التي تحتوي على بنية متغير محلي متسلسلة.حدد قيمة فارغة إذا كانت الطريقة لا تحتوي على متغيرات محلية." المشكلة هي أن هذا كل ما تقوله، ولا يمكنني معرفة تنسيق "توقيع المتغير المحلي المتسلسل." لقد حاولت البحث في مواصفات ECMA-335، ولكن كل ما وجدته هو كيفية تحديد المتغيرات المحلية في CIL غير المجمعة.إذا كان بإمكان أي شخص مساعدتي في معرفة ذلك، فسيكون ذلك موضع تقدير كبير.

أيضا، الحجة الأخيرة هي IEnumerable<int> tokenFixups, ، وهو "مجموعة من القيم التي تمثل الإزاحات في il، تحدد كل منها بداية الرمز المميز الذي يمكن تعديله.حدد قيمة فارغة إذا كانت الطريقة لا تحتوي على رموز مميزة يجب تعديلها.".أظن أنني لن أحتاج إلى استخدام هذه الأشياء، لكني أود أن أعرف ما هي على أي حال.

شكرا ، براندون

هل كانت مفيدة؟

المحلول

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

ستحتاج إلى فئة SignatureHelper.الإصلاحات مخصصة فقط للمترجمين الذين يترجمون التعليمات البرمجية الأصلية إلى IL، مثل C++/CLI.- هانز باسانت 10 مارس الساعة 13:02

لذا...للحصول على مصفوفة البايت للتوقيعات المحلية، يمكنك تنفيذ هذا الكود:

var sig = SignatureHelper.GetLocalVarSigHelper(this.module);
sig.AddArgument(typeof(int)); //Local #0 is of type int
...
sig.AddArgument(typeof(string)); //Local #n is of type string
var sigArray = sig.GetSignature();

ومن أجل تعيين نص الطريقة على MethodBuilder، عليك الاتصال

MethodBuilder.SetMethodBody(il, maxStack, sigArray, handlers, fixups);

...حيث هو byte[] مع تعليمات IL صالحة (انظر هذه الصفحة)، maxStack هو عدد صحيح مع عدد النقاط التي سيتم حجزها على المكدس للطريقة، والمعالجات هي System.Reflection.Emit.ExceptionHandler[], ، والإصلاحات هي أ int[] المصفوفة التي يمكن تجاهلها (مع استثناء واحد، انظر أدناه.)

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

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