CGO. I there way to iterate elements over C char buffer?

448 views
Skip to first unread message

Viacheslav Chumushuk

unread,
Jun 10, 2011, 10:09:52 AM6/10/11
to golang-nuts
Hi, there.

I have a little question about C and Go interaction.
Imaginge that we have a C function which returns pointer to some buffer.

> char *foo() // Please, forget about size, it is not importent for us now.

So, the problem (in Go code) is to copy this buffer's content to Go-array.

> buf := C.foo()
> ???

I can't find the way to do it. Any ideas?

--
Best regards, Viacheslav Chumushuk
email/jabber: vo...@root.ua
Ukraine, Khmelnitsky

Jan Mercl

unread,
Jun 10, 2011, 10:24:03 AM6/10/11
to golan...@googlegroups.com
On Friday, June 10, 2011 4:09:52 PM UTC+2, Viacheslav Chumushuk wrote:

I have a little question about C and Go interaction.
Imaginge that we have a C function which returns pointer to some buffer.

> char *foo() // Please, forget about size, it is not importent for us now.

So, the problem (in Go code) is to copy this buffer's content to Go-array.

> buf := C.foo()
> ???

I can't find the way to do it. Any ideas?

If the C character buffer is a C string, i.e. it's null terminated, then it should be possible to use C.GoString(). Example e.g. here:

Viacheslav Chumushuk

unread,
Jun 10, 2011, 10:38:11 AM6/10/11
to golan...@googlegroups.com
No, it is simple raw bytes buffer.
And I'd like to convert it to []int8 array.

On Fri, Jun 10, 2011 at 07:24:03AM -0700, Jan Mercl <jan....@nic.cz> wrote:
> If the C character buffer is a C string, i.e. it's null terminated, then it
> should be possible to use C.GoString(). Example e.g. here:
> http://golang.org/misc/cgo/stdio/file.go

--

Jan Mercl

unread,
Jun 10, 2011, 10:46:12 AM6/10/11
to golan...@googlegroups.com
On Friday, June 10, 2011 4:38:11 PM UTC+2, Viacheslav Chumushuk wrote:
No, it is simple raw bytes buffer.
And I'd like to convert it to []int8 array.

Is the buffer of fixed size? If so, then it should be possible to declare a Go [size]int8 array and do something like:
GoBuf := *(*[size]int8)(unsafe.Pointer(C.foo())) // untested, could be completely broken

The situation with a variable length C buffer would require a more fiddling, but is also doable, I believe.

Viacheslav Chumushuk

unread,
Jun 14, 2011, 12:58:52 PM6/14/11
to golan...@googlegroups.com
Sorry for the late responce.
Your code works perfect. But in my case buffer is sized dynamically.
And, as I'm understanding, without size Go converts it to slice.

--

Gustavo Niemeyer

unread,
Jun 14, 2011, 1:08:32 PM6/14/11
to golan...@googlegroups.com
> Sorry for the late responce.
> Your code works perfect. But in my case buffer is sized dynamically.
> And, as I'm understanding, without size Go converts it to slice.

Don't use unsafe unless you really understand the implications,
otherwise you'll see strange crashes at weird locations. Instead, use
GoStringN:

s := C.GoStringN(foo, n)

--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/blog
http://niemeyer.net/twitter

Viacheslav Chumushuk

unread,
Jun 14, 2011, 1:23:14 PM6/14/11
to golan...@googlegroups.com
But how to convert it to a slice, not a string?

--

Gustavo Niemeyer

unread,
Jun 14, 2011, 1:42:17 PM6/14/11
to golan...@googlegroups.com
> But how to convert it to a slice, not a string?

You can do []byte(s)

These documents are very helpful for figuring the basics out:

http://golang.org/doc/effective_go.html
http://golang.org/doc/go_tutorial.html

Viacheslav Chumushuk

unread,
Jun 14, 2011, 1:47:59 PM6/14/11
to golan...@googlegroups.com
Thanks for help.
I think now I'll figure it out.

--

Reply all
Reply to author
Forward
0 new messages