السلام عليكم ورحمة الله وبركاته.
في الإصدارات السابقة Go 1.5 وأسفل، لم يكن هنالك مشكلة من تمرير مؤشرات ذاكرة Go إلى C، الآن ومع Go 1.6 أصبحت تخرج أخطاء Runtime إن مررتَ مؤشر Go إلى C، وقرأتُ عدّة مراجع لا تنصح بذلك لا تنصح بالتمرير من Go إلى C، لدي بعض الإستفسارات إنطلاقًا من هذا:
إلى أي مدى هو آمن الإحتفاظ بمتغيير Go بداخل C لعملية طويلة في Theard مختلف عن Go بحيث تصبح القيمة غير مستخدمة في Go لكنها مستخدمة في C هل ستحذف؟
إذا حجزتُ قيمة بداخل C ومررتها إلى Go كقيمة خاصة بـGo هل ستحدث مشاكل في Go؟ وهل ستعتبر قيمة خاصة بـCGo لا تحرر؟ وهل أُحررها فيما بعد باستخدام free؟
هذه الشيفرة كمثال على الأثنين التمرير من C إلى Go ومن الأخيرة إلى C:
package main
import (
"fmt"
"unsafe"
)
/*
#include <stdlib.h>
#include <stdio.h>
const int initArrayLen = 4;
void*
goArray() {
char* array = (char*)malloc(initArrayLen * sizeof(char*));
array[0] = 47;
array[1] = 78;
array[2] = 124;
array[3] = 240;
return array;
}
void
iterGoSlice(void* ptr) {
ptr = *(void**)ptr;
int len = *((char*)ptr + sizeof(void*)), i;
printf("Go Slice Length: %d\n", len);
for (i=0; i<len; i++)
printf("GoSlice[%d] = %d\n", i, (*(char**)ptr)[i]);
}
*/
import "C"
func main() {
arrayFromC := *(*[4]byte)(C.goArray())
goSlice := []byte{32, 12, 43, 54}
fmt.Println("CArray length", len(arrayFromC))
for i, val := range arrayFromC {
fmt.Printf("CArray[%d] = %d\n", i, val);
}
// Go 1.6 تمنع تمرير مؤشراتها إلى C مباشرًا
gptr := unsafe.Pointer(&goSlice)
cptr := C.malloc(C.size_t(unsafe.Sizeof(gptr)))
*(*unsafe.Pointer)(cptr) = gptr;
defer C.free(cptr)
C.iterGoSlice(cptr)
}
التعليقات