2015-05-27 14 views
6

Mam funkcję Go, która otacza funkcję proc_name(pid,...) z lib_proc.h.Problem interoperacyjności C i Go z udziałem C.free()

Ta pełna C prototyp:


int proc_name(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 

które można znaleźć tutaj /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/libproc.h (przynajmniej w moim systemie).

Wynika kod Go:


package goproc 

    /* 
    #include "libproc.h" 

    int call_proc_name(int pid, char *name, int name_size) { 
     return proc_name(pid, name, name_size); 
    } 
    */ 
    import "C" 
    import "unsafe" 
    import "strings" 

    type DarwinProcess struct { 
     Process 
    } 

    func (DarwinProcess) NameOf(pid int) string { 
     name := C.CString(strings.Repeat("\x00", 1024)) 
     defer C.free(unsafe.Pointer(name)) 
     nameLen := C.call_proc_name(C.int(pid), name, C.int(1024)) 
     var result string 

     if (nameLen > 0) { 
      result = C.GoString(name); 
     } else { 
      result = "" 
     } 

     return result; 
    } 

Ten kod nie będzie kompilować, chyba że wezwanie do C.free(unsafe.Pointer(...)) i import "unsafe" klauzuli zostaną usunięte. DarwinProcess::NameOf(pid) Metoda przeznaczona jest wyłącznie do pracy pod Mac OS X i faktycznie działa, jeśli C.free(...) jest usunięty z kodu.

W rzeczywistej postaci po go build pojawia się następujący komunikat o błędzie: could not determine kind of name for C.free (i nic więcej, to jest całe wyjście kompilatora).

Usunięcie C.free(...) jest dla mnie nie do przyjęcia, muszę znaleźć sposób na prawidłowe zwolnienie pamięci przydzielonej z C.CString().

Jestem zdziwiony, ponieważ zgodnie z documentation, wszystko dzieje się prawidłowo. Nie byłem w stanie znaleźć rozwiązania ani szukać tutaj, ani w Internecie.

+0

Czy próbowałeś dodać '#include ' do komentarza cgo? –

Odpowiedz

5

libproc.h nie obejmuje stdlib.h, gdzie zadeklarowano free(). Z tego powodu kompilator nie może rozpoznać nazwy. Po dodaniu #include <stdlib.h> na początku komentarza cgo zablokuj pomyślnie swój kod w moim systemie.

+0

+1 To działało idealnie i odpowiada na moje pytanie. Szczerze mówiąc zostałem wprowadzony w błąd przez dokumentację, która wydaje się sugerować, że 'C.free()' jest częścią specjalnego pakietu 'C'. Ale w rzeczywistości mówimy o standardowym 'stdlib :: free()'. – gsscoder

+0

Podobnie jak inne środowiska uruchomieniowe, również w Go libs brakuje API do zarządzania już działającymi procesami systemu operacyjnego, więc próbuję go napisać. Na razie tylko stub (https://github.com/gsscoder/goproc). – gsscoder