2015-10-04 79 views
2

我使用Cgo使用C庫以及除回調以外的所有優點。庫具有回調setter,它使用指向回調函數的指針。回調函數本身寫入go並使用Cgo語法導出。
問題:我可以使用char *參數進行製作和導出功能,但不能使用const char *Cgo:無法找到使用const char *參數的回調方法

代碼來說明:
test.go

package main 

/* 
typedef void (*cb_func)(const char *, int); 
void callback(cb_func); 
void myFunc(const char *, int); 
*/ 
import "C" 
import (
     "fmt" 
     "unsafe" 
) 

//export myFunc 
func myFunc(buf *C.char, ln C.int) { 
     fmt.Printf("Got: %s\n", C.GoStringN(buf, ln)) 
} 

func main() { 
     C.callback((C.cb_func)(unsafe.Pointer(C.myFunc))) 
} 

test.c的

typedef void (*cb_func)(const char *, int); 

void callback(cb_func cb) { 
     cb("test", 4); 
} 

輸出從go build

In file included from $WORK/test/_obj/_cgo_export.c:2:0: 
./test.go:54:13: error: conflicting types for 'myFunc' 
./test.go:7:6: note: previous declaration of 'myFunc' was here 
void myFunc(const char *, int); 
    ^
/tmp/go-build994908053/test/_obj/_cgo_export.c:9:6: error: conflicting types for 'myFunc' 
void myFunc(char* p0, int p1) 
    ^
In file included from $WORK/test/_obj/_cgo_export.c:2:0: 
./test.go:7:6: note: previous declaration of 'myFunc' was here 
void myFunc(const char *, int); 
    ^

如果沒有const限定符代碼編譯並按預期工作。

什麼可以使用inspi *C.char C語言中得到const字符串?

回答

4

由於Go沒有const指針修飾符,因此無法從Go代碼中轉換此行爲。 cgo將始終生成沒有const修飾符的標頭。這也是您的代碼無法正確構建的原因:cgo僅基於它所知道的內容創建myFuncbuf應該是char*,而不是const char*

處理此問題的最佳方法是在C端使用包裝器,該包裝器將該參數投射到const char*。在你的情況下,將myFunc的定義更改爲void myFunc(char*, int)就足夠了。將函數傳遞給cb_func將自動工作,無論從鑄造myFunc(*cb_func)(const char*,int)只會添加類型信息,但不會更改內存佈局。

+0

好的,包裝是一個解決方案。然而,現在我重新定義了回調原型而沒有const的直接在go文件中(就像我上面的例子)。它看起來有點黑,但也起作用。 – sisoft

相關問題