2015-05-27 61 views
6

我有一個Go函數,它包含proc_name(pid,...)函數lib_proc.h涉及C.free的C和Go互操作性問題()

這是完整的C語言


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

,可以在這裏找到/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/libproc.h(至少在我的系統)。

它遵循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; 
    } 

此代碼不會,除非調用編譯爲C.free(unsafe.Pointer(...))import "unsafe"條款被刪除。 DarwinProcess::NameOf(pid)方法僅用於Mac OS X它實際上工作如果從代碼中刪除C.free(...)

go build之後的實際形式中,我收到以下錯誤消息: could not determine kind of name for C.free(沒有別的,這是整個編譯器輸出)。

刪除C.free(...)是我不能接受的,我必須找到如何正確釋放分配與C.CString()分配的內存。

我很困惑,因爲根據documentation,一切都做得很好。我一直無法找到解決方案,也沒有在這裏或在網上搜索。

+0

你有沒有嘗試在你的cgo評論中加入'#include '? –

回答

5

libproc.h不包括stdlib.h,其中free()被聲明。因此,編譯器無法解析名稱。在cgo註釋塊的開頭添加了#include <stdlib.h>後,您的代碼在我的系統上成功構建。

+0

+1這工作完美,並回答我的問題。說實話,我被文檔誤導了,似乎表明'C.free()'是特殊'C'包的一部分。但實際上我們正在談論標準的'stdlib :: free()'。 – gsscoder

+0

與其他運行時一樣,lib庫缺少用於管理已經運行的OS進程的API,所以我試圖編寫一個。現在只是一個存根(https://github.com/gsscoder/goproc)。 – gsscoder