2016-03-19 9 views
-2

habe ich eine C-Funktion wie diesesCGO: Wie Doppel Array von C zurück zu gehen

double* c_func(int n_rows) { 
    double result[n_rows]; 
    for (int i = 0; i < n_rows; ++i) { 
    result[i] = (double)i; 
    } 
    return result; 
} 

Und ich diese Go-Funktion der C-Doppel zu verarbeiten:

// convert C double pointer to float64 slice ... 
func doubleToFloats(in *C.double, length int) []float64 { 
    out := make([]float64, length, length) 

    start := unsafe.Pointer(in) 
    size := unsafe.Sizeof(C.double(0)) 
    for i := 0; i < length; i++ { 
     val := *(*C.double)(unsafe.Pointer(uintptr(start) + size*uintptr(i))) 
     out[i] = float64(val) 
    } 
    return out 
} 

Diese manchmal Werke aber manchmal nicht. Wenn es nicht funktioniert, ist es so etwas wie dies zurück:

[0 1 2 3 4 5 6 7 8 9 10 2.53e-321 3.32018606e-316 4.24664374149e-312 4.24399158193e-312 1.1383e-320 3.31882387e-316 3.71924634e-316 3.31885594e-316 3.71924634e-316 5e-324 0 4.6950308e-316 4.24664374149e-312 3.7175681e-316 3.3200616e-316]

, die mir wie etwas Speicher Ausgabe sieht ...

Ich bin nicht sicher, ob dies der richtige Weg ist, doppelt zu handhaben zurück Array von C in Go. Wenn ja, wie behebe ich das Problem (was gelegentlich auftritt). Wenn nein, was ist der richtige Weg, um das zurückgegebene Doppel-Array von C zu behandeln?

Danke.

Antwort

-1

OK, also habe ich einen einfachen Weg gefunden, dies zu erreichen.

Wir verwenden calloc ersten Speicher für das Array zuzuordnen:

double* c_func(int n_rows) { 
    double* result; 
    result = calloc(n_rows, sizeof(double)); 
    for (int i = 0; i < n_rows; ++i) { 
     result[i] = (double)i; 
    } 
    return result; 
} 

und danach haben wir einfach die Daten in die richtige Art in Go umwandeln. Der Trick besteht darin, C.free zu verwenden, um den von C-Seite zugewiesenen Speicher freizugeben.

// convert C double pointer to float64 slice ... 
func doubleToFloats(in *C.double, size int) []float64 { 
    defer C.free(unsafe.Pointer(in)) 
    out := (*[1 << 30]float64)(unsafe.Pointer(in))[:size:size] 
    return out 
} 
0

In C wird der zurückgegebene Zeiger veraltet sein. Sie müssten die Tabelle wie double * result = calloc (sizeof (double), nrows) --- die auch eine Möglichkeit haben würde, um den Speicher zu befreien benötigen.

+0

Dann, was ist der richtige Weg, dies zu tun? – lazywei