私はbinary.Write()関数を使用してデータをパックするbyte.Bufferを持っています。私は、このバイト配列をC関数に送る必要があります。 Go 1.6を使って私はこれを理解することに成功しませんでした。Go [] byteをC * charに変換する
buf := new(bytes.Buffer) //create my buffer
....
binary.Write(buf, binary.LittleEndian, data) //write my data to buffer here
addr := (*C.uchar)(unsafe.Pointer(&buf.Bytes()[0])) //convert buffers byte array to a C array
rc := C.the_function(addr, C.int(buf.Len())) //Fails here
それは言ってC関数を呼び出す行に失敗します。
panic: runtime error: cgo argument has Go pointer to Go pointer
C関数:
int the_function(const void *data, int nbytes);
私は仕事に以下を得ることができたが、それは間違っていると感じましたバイト配列を文字列に変換します。これを行うより良い方法はありますか?この方法はデータに副作用を与える危険性がありますか?
addr := unsafe.Pointer(C.CString(string(buf.Bytes()[0]))
これも厳密なcgoポインタルールを導入したGo 1.6で動作する必要があります。
ありがとうございます。
[]バイトをC文字列に変換するのは良い考えではありません。 []バイトの '\ 0'はc文字列を表し、c文字列の長さはorigin []バイトの長さと等しくない可能性があります。 –
@bronzeman:明らかに問題の関数は引数としてバッファの長さをとり、NULL終了文字列を期待していません。 'C.CString'は必要に応じてヌルバイトを追加しますが、正確な文字列長を渡すことでヌルバイトをスキップします。 – JimB