الخطأ: تلقي رمز خطأ "0xC0000005" عندما يتم تشغيل حدث أصلي أو unhooked

الأعراض

عند إطلاق النار حدث __raise أو إلغاء ربط الأحداث الأصلية (__unhook) في تطبيق غير مدار، قد تتلقى رسالة الخطأ التالية:
استثناء غير معالج في
العنوان الظاهري
قابل للتنفيذ: 0xC0000005: انتهاك وصول قراءة الموقع عنوان ظاهري
حيث
العنوان الظاهري و
القابلة للتنفيذ هي القيم الخاصة بالتطبيق الخاص بك.

السبب

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

الحل البديل

للتغلب على هذه المشكلة، استخدم إحدى الطرق التالية:

الطريقة الأولى

تعريف منشئ مصدر الحدث في نطاق الفئة. للقيام بذلك، استبدال التعليمات البرمجية الموجودة:
struct A {__event void Event(); 
A();
void bar(){}
};
//Constructor defined outside class scope.
A::A() { }
التعليمة البرمجية التالية:
struct A {__event void Event(); 
A() { }; //Contructor defined in class scope.
void bar(){}
};

الطريقة الثانية

تتضمن التعليمات البرمجية التهيئة eventHandlerList في منشئ مصدر الحدث. وهذا يفترض أن الملف.cpp الذي يحتوي على تعريف فئة مصدر الحدث event.cpp. يمكن تخزين التعليمات البرمجية المدخلة التي يتم إنشاؤها بواسطة برنامج التحويل البرمجي في ملف متوسطة بمساعدة خيار برنامج التحويل البرمجي خط الأوامر /Fx .
  1. في موجه الأوامر، اكتب الأمر التالي:
    cl /Fx event.cpp
    التعليمات البرمجية المدخلة التي يتم إنشاؤها بواسطة المحول البرمجي تم حفظها في ملف مع. الملحق mrg.cpp. يعد الملف مع التعليمات البرمجية التي تم إدراجها ل event.cpp، event.mrg.cpp.
  2. في المتوسط الملف الذي يتم إنشاؤه (event.mrg.cpp)، إضافة التعليمات البرمجية التالية إلى منشئ مصدر الحدث:
    • إذا تم تعريف فئة مصدر الحدث الذي يدعى A في مساحة اسم X، أضف التعليمات البرمجية التالية:
      __eventHandlerList_X_A_Event = 0;
      المنشئ كل.
    • إذا لم يتم تعريف فئة مصدر الحدث الذي يدعى A في أي مساحة اسم، أضف التعليمات البرمجية التالية:
      __eventHandlerList_A_Event = 0;
      المنشئ كل.
    حيث هو فئة مصدر الحدث، X هو مساحة الاسم لا، و الأحداث الحدث تعريفها بواسطة الكلمة الأساسية __event الحدث في فئة المصدر.
  3. ترجمة ملف المتوسطة في موجه الأوامر باستخدام الأمر التالي:
    cl event.mrg.cpp

الحالة

أقرت Microsoft أن هذا هو الشوائب في منتجات Microsoft المسردة في بداية هذه المقالة.

مزيد من المعلومات

خطوات إعادة إنشاء المشكلة


يمكن إعادة إنشاء المشكلة مع أحد الموقفين التاليين:

السيناريو 1

تعريف مصدر حدث داخل مساحة اسم. بالإضافة إلى ذلك، يتم تطبيق مصدر الحدث ومتلقي الحدث بنفس الفئة أو البنية. للقيام بذلك، اتبع الخطوات التالية:
  1. في Visual Studio.NET, إنشاء مشروع "تطبيق وحدة تحكم Win32 Visual c + +".
  2. بشكل افتراضي الملف.cpp الذي تم إنشاؤه للتطبيق الخاص بك، استبدال التعليمات البرمجية الموجودة مع التعليمات البرمجية التالية:
    #include "stdafx.h"namespace X 
    {
    //Both event source and event receiver
    struct A {
    __event void Event();
    A();
    void bar(){}
    };
    }

    X::A::A() { }

    int main()
    {
    X::A a;
    __hook(&X::A::Event, &a, &X::A::bar, &a);
    a.Event();
    __unhook(&X::A::Event, &a, &X::A::bar, &a);
    }
  3. بناء وتشغيل التطبيق.
تظهر رسالة الخطأ الموضحة في قسم "الأعراض" من هذه المقالة.

السيناريو 2

تعرف مصدر الحدث ومتلقي الحدث في اثنين من مختلف الفئات أو البنيات. للقيام بذلك، اتبع الخطوات التالية:
  1. في Visual Studio.NET, إنشاء مشروع "تطبيق وحدة تحكم Win32 Visual c + +".
  2. بشكل افتراضي الملف.cpp الذي تم إنشاؤه للتطبيق الخاص بك، استبدال التعليمات البرمجية الموجودة مع التعليمات البرمجية التالية:
    #include "stdafx.h"//Event source
    struct A {
    __event void Event();
    A();
    };

    //Event Receiver
    struct B
    {
    void bar();
    };

    void B::bar(){}
    A::A() { }

    int main()
    {
    A a;
    B b;
    __hook(&A::Event, &a, &B::bar, &b);
    a.Event();
    __unhook(&A::Event, &a, &B::bar, &b);
    }
  3. بناء وتشغيل التطبيق.
تظهر رسالة الخطأ الموضحة في قسم "الأعراض" من هذه المقالة.

تحدث المشكلة بسبب المحول البرمجي يقوم بإنشاء التعليمات البرمجية المدخلة غير صحيح للدالة الإنشائية لمصدر الحدث. لعرض التعليمات البرمجية المدخلة التي يتم إنشاؤها بواسطة برنامج التحويل البرمجي، ترجمة التعليمات البرمجية السابقة في موجه الأوامر كما يلي:
cl /Fx event.cpp
حيث يتم حفظ التعليمات البرمجية في event.cpp. تتوفر التعليمات البرمجية التي يتم إنشاؤها بواسطة برنامج التحويل البرمجي في ملف يسمى event.mrg.cpp. لا يحتوي منشئ فئة الحدث على رمز التهيئة eventHandlerList التالية عند تعريف منشئ فئة الحدث خارج نطاق الفئة:
  • عندما يتم تعريف فئة مصدر الحدث الذي يدعى A في مساحة اسم X
    __eventHandlerList_X_A_Event = 0;
  • عندما لم يتم تعريف فئة مصدر الحدث الذي يدعى A في أي مساحة اسم
    __eventHandlerList_A_Event = 0;
حيث يعتبر فئة مصدر الحدث و X هو مساحة الاسم لا الحدث هو الحدث التي تم تعريفها بواسطة الكلمة الأساسية __event مصدر الحدث في الفئة.

ملاحظة: وبالمثل يعرض الكلمة الحدث __raise نفس السلوك التي يتم عرضها حسب الكلمة الأساسية الحدث __unhook .

المراجع

للحصول على معلومات إضافية حول الحدث الأصلي معالجة الكلمات الأساسية والسمات، راجع موقع MSDN على ويب:
الكلمات الأساسية معالجة الحدث
http://msdn2.microsoft.com/en-us/library/6f01ek09(vs.71).aspx
خصائص

رقم الموضوع: 811193 - آخر مراجعة: 15‏/01‏/2017 - المراجعة: 1

تعليقات