2015-05-27 11 views
6

Ich habe eine Go-Funktion, die die proc_name(pid,...)-Funktion von lib_proc.h umschließt.C und Go Interoperabilitätsproblem mit C.free()

Dies ist der komplette C Prototyp:


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

, die hier gefunden werden kann /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/libproc.h (zumindest auf meinem System).

Es folgt Go Code:


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; 
    } 

Dieser Code wird, es sei denn der Aufruf an C.free(unsafe.Pointer(...)) und import "unsafe" Klausel nicht kompiliert werden entfernt. DarwinProcess::NameOf(pid) Methode soll nur auf Mac OS X und funktioniert es funktioniert, wenn C.free(...) aus dem Code entfernt wird.

In seiner tatsächlichen Form nach go build bekomme ich folgende Fehlermeldung: could not determine kind of name for C.free (und nichts mehr, das ist die gesamte Compiler-Ausgabe).

Entfernen C.free(...) ist nicht akzeptabel für mich, ich muss finden, wie man den mit C.CString() zugeteilten Speicher richtig freigibt.

Ich bin verwirrt, da nach documentation alles richtig gemacht wird. Ich konnte weder hier noch im Internet eine Lösung finden oder suchen.

+0

Haben Sie versucht, '#include ' in Ihrem CGO-Kommentar hinzuzufügen? –

Antwort

5

libproc.h enthält nicht stdlib.h, wobei free() deklariert ist. Daher kann der Compiler den Namen nicht auflösen. Nachdem ich #include <stdlib.h> am Anfang des cgo Kommentarblocks hinzugefügt habe, baute sich dein Code erfolgreich auf meinem System auf.

+0

+1 Das hat perfekt funktioniert und beantwortet meine Frage. Um ehrlich zu sein, wurde ich durch Dokumentation irregeführt, die nahelegt, dass 'C.free()' Teil des speziellen 'C'-Pakets ist. Aber in Wirklichkeit sprechen wir von Standard 'stdlib :: free()'. – gsscoder

+0

Wie andere Laufzeiten auch fehlt Go libs eine API zur Verwaltung bereits laufender OS-Prozesse, also versuche ich eine zu schreiben. Für jetzt nur einen Stub (https://github.com/gsscoder/goproc). – gsscoder