طريقة جيدة أو موصى بها لترجمة بنية ج إلى بنية

StackOverflow https://stackoverflow.com//questions/23004474

  •  20-12-2019
  •  | 
  •  

سؤال

أنا باستخدام سغو لتطوير مكتبة ملزمة من الذهاب.اسمحوا لي أن تنظر في بنية ج وتذهب البنية على النحو التالي.

struct cons_t {
  size_t type;
  cons_t *car;
  cons_t *cdr;
};

cons_t* parse(const char *str);

وهذا هو هيكل غو

type Cons struct {
  type int;
  car *Cons;
  cdr *Cons;
}

لتنفيذ وظيفة الذهاب على النحو التالي, ما هي أفضل طريقة لتنفيذ ترانسلاتيكونس 2جوكنس?

func Parse (str string) *Cons {
  str_ptr := C.CString(string);
  cons_ptr := C.parse(str_ptr);
  retCons := TranslateCCons2GoCons(cons_ptr);
  return retCons;
}

جوابي الأول هو على النحو التالي.

/*#cgo
int getType(cons_t *cons) {
    return cons->type;
}
cons_t *getCar(cons_t *cons) {
  return cons->car;
}
cons_t *getCdr(cons_t *cons) {
  return cons->cdr;
}
*/

func TranslateCCons2GoCons (c *C.cons_t) Cons {
  type := C.getType(c);
  car := C.getCar(c);
  cdr := C.getCdr(c);
  // drop null termination for simplicity
  return Cons{type, TranslateCCons2GoCons(car), TranslateCCons2GoCons(cdr)};
}

هل هناك أي طريقة أفضل?

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

المحلول

أود أن أوصي ضد وظائف أسيسور.يجب أن تكون قادرا على الوصول إلى حقول البنية ج مباشرة ، والتي سوف تجنب الذهاب -> وظيفة ج استدعاء النفقات العامة (وهو غير تافهة).لذلك قد تستخدم شيئا مثل:

func TranslateCCons2GoCons (c *C.cons_t) *Cons {
    if c == nil {
        return nil
    }
    return &Cons{
        type: int(c.type),
        car: TranslateCCons2GoCons(c.car),
        cdr: TranslateCCons2GoCons(c.cdr),
    }
}

أيضا ، إذا قمت بتخصيص سلسلة ج مع C.CString, ، تحتاج إلى تحريره.لذلك الخاص بك Parse وظيفة يجب أن تبدو شيئا من هذا القبيل:

func Parse (str string) *Cons {
    str_ptr := C.CString(str)
    defer C.free(unsafe.Pointer(str_ptr)
    cons_ptr := C.parse(str_ptr)
    retCons := TranslateCCons2GoCons(cons_ptr)
    // FIXME: Do something to free cons_ptr here.  The Go runtime won't do it for you
    return retCons
}

نصائح أخرى

يمكنك استخدام الهياكل C في Goأبسط طريقة ستكون فقط

giveacodicetagpre.

أي وظيفة في C هي الآن مجرد تعزز في الذهاب

giveacodicetagpre.

يحتوي هذا على النفقات العامة الخاصة به، حيث يجب عليك القيام بتحويل من النوع على الوصول إلى عنصر.إذن ما كان قبل struct الآن

giveacodicetagpre.

حل وسط متوسط يمكن استخدامه حيث تخزن الحقول إلى جانب نوع C لسهولة الوصول إلى

giveacodicetagpre.

المشكلة الحقيقية الوحيدة مع هذا هو أنه إذا كنت تدعو وظائف C كثيرا، فيمكن أن يؤدي ذلك إلى إدخال صيانة النفقات العامة في إعداد حقول التنقل:

giveacodicetagpre.

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