"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > كيفية الوصول إلى حقول الاتحاد في CGo الخاص بـ Go؟

كيفية الوصول إلى حقول الاتحاد في CGo الخاص بـ Go؟

تم النشر بتاريخ 2024-11-06
تصفح:140

How to Access Union Fields in Go\'s CGo?

تحويل حقول الاتحاد إلى أنواع Go في Golang CGo

عند العمل مع هياكل C في Golang CGo، يمكن أن يمثل الوصول إلى الحقول الموحدة تحديًا. يتضمن السيناريو الشائع الوصول إلى حقل ui32v في اتحاد القيمة داخل بنية C، كما في المثال التالي:

struct _GNetSnmpVarBind {
  guint32       *oid;       /* name of the variable */
  gsize     oid_len;    /* length of the name */
  GNetSnmpVarBindType   type;       /* variable type / exception */
  union {
    gint32   i32;           /* 32 bit signed   */
    guint32  ui32;          /* 32 bit unsigned */
    gint64   i64;           /* 64 bit signed   */
    guint64  ui64;          /* 64 bit unsigned */
    guint8  *ui8v;          /*  8 bit unsigned vector */
    guint32 *ui32v;         /* 32 bit unsigned vector */
  }         value;      /* value of the variable */
  gsize     value_len;  /* length of a vector in bytes */
};

ملاحظة: في هذا المثال، نحن نستخدم نظامًا أساسيًا 64 بت.

الأسلوب الفاشل: التحويل إلى uint64 والإرسال

قد يتضمن النهج الأولي تحويل محتويات حقل الاتحاد إلى uint64، على افتراض أنه يمثل عنوان ذاكرة، ثم تحويل uint64 إلى *_Ctype_guint32. ومع ذلك، سيؤدي هذا الأسلوب إلى خطأ في تحويل النوع.

النهج الصحيح: استخدام عنوان الاتحاد

بدلاً من ذلك، يتضمن النهج الصحيح استخدام عنوان الاتحاد. الاتحاد نفسه. في CGo، يتم عرض الاتحاد كمصفوفة بايت كبيرة بما يكفي لاستيعاب أكبر عضو فيه. في هذه الحالة، يبلغ حجم هذا الصفيف ثمانية بايت ([8] بايت). باستخدام عنوان هذه المصفوفة، يمكننا إرسالها مباشرة إلى النوع المطلوب.

بالنسبة للبيانات المسماة C._GNetSnmpVarBind، يوضح التعليمة البرمجية التالية هذا الأسلوب:

guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))

تقسيم الكود:

  • &data. value[0] تحصل على عنوان البايت الأول في اتحاد القيمة.
  • unsafe.Pointer(&data.value[0]) يحول هذا العنوان إلى مؤشر من النوع unsafe.Pointer.
  • (**C.guint32)(unsafe.Pointer(&data.value[0])) يفسر الذاكرة المشار إليها بواسطة unsafe.Pointer(&data.value[0]) على أنها **C.guint32، ويصل بشكل فعال إلى ui32v الحقل كمؤشر إلى guint32.

يسمح هذا الأسلوب المبسط بالوصول المباشر إلى حقول الاتحاد في كود Go.

أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3