تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
إشارة مرجعية Pointer
#1
مقدمة :

في واقع الأمر و بشكل مبدئي لقد احترت قليلا حين أردت أت أختار عنوانا لهذا الموضوع لكن في النهاية قررت استخدم كلمة Pointer للموضوع
لذلك اسمحوا لي أولا أن أقوم بتوضح معني هذه الكلمة

كلمة Pointer ترجمتها الحرفية في اللغة العربية تساوي كلمة مؤشر
والمعني هنا كأنك تشير لشئ مجهول وتقول كلمة هذا
وكلمة هذا في اللغة العربية عبارة عن لفظ إشارة لشئ مجهول لا نعرف نوعه او ماهيته

وبرمجيا فإن Pointer في لغة #C تساوي كلمة Value Type في لغة الفيجوال بيسك دوت نت
و جميع الأشكال التالية تعتبر Pointer

1- جميع الأنواع تعتبر Pointer وهي  , sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool
2- أي Structure جديد تبنيه وتكتب الكود الخاص به يعتبر Pointer
3- أيضا Enum يعتبر Pointer

الهدف :

لعل واحدة من أكبر المشاكل التي تواجه المبرمج هي أنه بعد تعريف متغير معين و استخدامه فإن GC Class يقوم بالتخلص من كل شئ في ذاكرة الكمبيوتر
وبالتالي حينما يريد المبرمج استرجاع قيمة هذا المتغير بعد  فترة زمنية قد لا يجد قيمته في ذاكرة الكمبيوتر
لذلك و بشكل مؤقت وهربا من هذه المشكلة قد يضطر المبرمج إلي تثبيت قيمة المتغير في أول البرنامج

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

ملحوظة هامة :

الفكرة محل النقاش يمكن استخدامها أثناء تشغيل البرنامج فقط 

خطوات التنفيذ :

حفظ البيانات
1- كتابة Structure بأي إسم تراه مناسبا و تضع به المتغيرات
2- تحويل هذا Structure الي مصفوفة بايت
3- حفظ مصفوفة البايت بشكل مؤقت تحت فهرس المشروع أو تحتفظ بها في اي مكان أخر تحدده أنت

إسترجاع البيانات
1- تقرأ مصفوفة البايت من الملف
2- تقوم بتحويل مصفوفة البايت الي Structure
3- تقرأ المتغيرات من هذا Structure و تستخدمها حين تريد

المثال الأول

افتح مشروع 
أضف للفورم باتون و Label
أضف الكلاس التالي للمشروع


PHP كود :
Public Structure StringPointer
    Public Source 
As String
End Structure 

أضف  الكلاس التالي للمشروع و هذا الكلاس سيكون ثابتا في جميع الأمثلة حيث الهدف منه تحويل Structure الي مصفوفة بايت و العكس

PHP كود :
Public Class PointerConverter(Of T As Structure)

 
   Private _value As T
    Private _bytes 
As Byte()

 
   Public Sub New(value As T)
 
       Me._value value
    End Sub

    Public Sub 
New(bytes As Byte())
 
       Me._bytes bytes
    End Sub

    Private 
Function ToBytes(value As T) As Byte()
 
       Dim length As Integer System.Runtime.InteropServices.Marshal.SizeOf(value)
 
       Dim bytes As Byte() = New Byte(length 1) {}
 
       Dim gc As System.Runtime.InteropServices.GCHandle Nothing
        Try
            gc 
System.Runtime.InteropServices.GCHandle.Alloc(bytesSystem.Runtime.InteropServices.GCHandleType.Pinned)
 
           System.Runtime.InteropServices.Marshal.StructureToPtr(valuegc.AddrOfPinnedObject(), True)
 
       Catch ex As Exception
        Finally
            If gc
.IsAllocated Then
                gc
.Free()
 
           End If
 
       End Try
 
       Return bytes
    End 
Function

 
   Private Function ToStructure(bytes As Byte()) As T
        Dim result 
As Nothing
        Dim gc 
As System.Runtime.InteropServices.GCHandle Nothing
        Try
            gc 
System.Runtime.InteropServices.GCHandle.Alloc(bytesSystem.Runtime.InteropServices.GCHandleType.Pinned)
 
           result CType((CObj(System.Runtime.InteropServices.Marshal.PtrToStructure(gc.AddrOfPinnedObject(), GetType(T)))), T)
 
       Catch ex As Exception
        Finally
            If gc
.IsAllocated Then
                gc
.Free()
 
           End If
 
       End Try
 
       Return result
    End 
Function

 
   Public Function ToStructure() As T
        Return Me
.ToStructure(Me._bytes)
 
   End Function

 
   Public Function ToBytes() As Byte()
 
       Return Me.ToBytes(Me._value)
 
   End Function

End Class 

اكتب الكود بالشكل التالي

PHP كود :
Public Class Form1
    Private Sub Form1_Load
(sender As ObjectAs EventArgsHandles MyBase.Load
        Dim s 
As String "Visual Basic Dot Net"
 
       Dim sp As StringPointer = New StringPointer With {.Source s}
 
       Dim bytes As Byte() = New PointerConverter(Of StringPointer)(sp).ToBytes
        Dim fileName 
As String ".\" + "data" + ".dat"
        IO.File.WriteAllBytes(fileName, bytes)
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim fileName As String = "
.\" + "data" + ".dat"
        Dim bytes As Byte() = IO.File.ReadAllBytes(fileName)
        Dim sp As StringPointer = New PointerConverter(Of StringPointer)(bytes).ToStructure
        Label1.Text = sp.Source
    End Sub
End Class 


المثال الثاني
وهنا سنجعل الأمر أكثر صعوبة قليلا 
افتح مشروع وأتوماتيكيا ستجد به الفورم رقم 1
أضف باتون و Label الي الفورم الأول
أضف للمشروع فورم أخر و هو سيكون الفورم رقم 2
أضف للمشروع الكلاس PointerConverter(Of T As Structure)
أضف الكلاس StringPointer الي المشروع

و اكتب الكود في الفورم الثاتي كالأتي


PHP كود :
Public Class Form2

    Private Sub Form2_Load
(sender As ObjectAs EventArgsHandles MyBase.Load
        Dim s 
As String "Visual Basic Dot Net"
 
       Dim sp As StringPointer = New StringPointer With {.Source s}
 
       Dim bytes As Byte() = New PointerConverter(Of StringPointer)(sp).ToBytes
        Dim fileName 
As String ".\" + "data" + ".dat"
        IO.File.WriteAllBytes(fileName, bytes)
    End Sub
End Class 

و في الفورم الأول اكتب الكود بالشكل التالي
عموما في المثال هذا سنستخدم الفورم الثاني لكي نبني الملف المراد حفظ الإشارة المرجعية به
ثم نغلق الفورم الثاني مباشرة حتي نتأكد أن كل ما فيه تم عمل Dispsoe له
ثم نعاود قراءة القيمة من الملف بالضغط علي الباتون في الفورم الأول


PHP كود :
Public Class Form1
    Private Sub Form1_Load
(sender As ObjectAs EventArgsHandles MyBase.Load
        Dim f 
As Form Form2
        f
.Show()
 
       f.Close()
 
   End Sub

    Private Sub Button1_Click
(sender As ObjectAs EventArgsHandles Button1.Click

        Dim fileName 
As String ".\" + "data" + ".dat"
        Dim bytes As Byte() = IO.File.ReadAllBytes(fileName)
        Dim sp As StringPointer = New PointerConverter(Of StringPointer)(bytes).ToStructure
        Label1.Text = sp.Source
    End Sub
End Class 

المثال الثاني موجود بالمرفقات وهو مكتوب بنسخة الفيجوال استوديو 2015

أتمني أن تكون الفكرة مفيدة للبعض منكم
و لاحقا سأحاول أن أضيف للموضوع أمثلة أخري أصعب قليلا
تقبلوا تحياتي


الملفات المرفقة
.rar   Test_StringPointer.rar (الحجم : 68.54 ك ب / التحميلات : 48)
Retired
الرد }}}
تم الشكر بواسطة: tryold , محمود صالح , ابو ليلى


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم