Go type not supported in export: [sha256.Size]byte

1,168 views
Skip to first unread message

Maarten Koopmans

unread,
Aug 18, 2015, 4:37:09 PM8/18/15
to golang-nuts
Well, Iguess ( hope!) this is easy for someone out here:

Go type not supported in export: [sha256.Size]byte when I compile with
#!/bin/bash
go build -buildmode=c-shared -o dynamite.a dynamite.go

and this minimal source:

package main

import (
  "crypto/sha256"
)

import "C"

//export Sha256data
func Sha256data(data []byte) [sha256.Size]byte {
  return sha256.Sum256(data)
}

sha256.Size is just 32, btw. So this leaves me wondering.... how do I get byte slices back from Go? And what is the idiomatic wy to do that?

Any help or insights greatly appreciated!

Thanks,

Maarten


Maarten Koopmans

unread,
Aug 18, 2015, 4:37:47 PM8/18/15
to golang-nuts
Build with Go 1.5RC1, FWIW

Op dinsdag 18 augustus 2015 22:37:09 UTC+2 schreef Maarten Koopmans:

andrey mirtchovski

unread,
Aug 18, 2015, 5:03:08 PM8/18/15
to Maarten Koopmans, golang-nuts
something like this, perhaps: http://play.golang.org/p/snzvlCl4Oy

note that a lot of the pain in conversions here is because it's a Cgo-exported Go function being called from Go, via Cgo :) you'll have less pain calling this from C directly.

comparison for correctness (not tested with zero-length data, YMMV)

$ go build t.go 
$ ./t
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
$ echo -n test | shasum -a 256
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08  -
$

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Maarten Koopmans

unread,
Aug 18, 2015, 5:43:39 PM8/18/15
to golang-nuts
Thank you. Do I need to include the extern function signature?

--Maarten

andrey mirtchovski

unread,
Aug 18, 2015, 7:40:46 PM8/18/15
to Maarten Koopmans, golang-nuts
you can find the signature in the "_cgo_export.h" file, as per https://github.com/golang/go/wiki/cgo

On Tue, Aug 18, 2015 at 3:43 PM, Maarten Koopmans <maarten....@gmail.com> wrote:
Thank you. Do I need to include the extern function signature?

--Maarten

Maarten Koopmans

unread,
Aug 19, 2015, 8:16:06 AM8/19/15
to golang-nuts, maarten....@gmail.com
Well, I've made progress, see https://play.golang.org/p/G__o3CzR8h  -> this one works.

The call side also gets the bytes back, but using strlen from libc I always get 34 (should be 32 for sha256).

My idea was to return a pointer to a struct with a pointer to the data and the actual length, but the compiler gave me multile beatings (not that I mind, that will teach me).

On a related note - len(hash256) insists "cannot call non-function len (type C.int)". And here I was thinking that hashing function return byte slices! (Just one of the many beatings).

As always, insights and tips are highly appreciated!

--Maarten

Op woensdag 19 augustus 2015 01:40:46 UTC+2 schreef andrey mirtchovski:

andrey mirtchovski

unread,
Aug 19, 2015, 9:29:19 AM8/19/15
to Maarten Koopmans, golang-nuts
> On a related note - len(hash256) insists "cannot call non-function len (type
> C.int)". And here I was thinking that hashing function return byte slices!
> (Just one of the many beatings).

the variable "len" (argument to the function) shadows the built-in
function "len".

Maarten Koopmans

unread,
Aug 19, 2015, 9:39:24 AM8/19/15
to golang-nuts, maarten....@gmail.com
Duh. Now let's see if I can return a struct.

Op woensdag 19 augustus 2015 15:29:19 UTC+2 schreef andrey mirtchovski:

Maarten Koopmans

unread,
Aug 19, 2015, 10:05:52 AM8/19/15
to golang-nuts, maarten....@gmail.com
Pffff. I have a really hard time returning a struct that holds the buffer and the length.

Given the above playground, is there a way to retrun structs from Go -> C?

I must say I find this piece of documentation a bit mor escattered than other dos (whcih are very good).

Thanks! Maarten

Op woensdag 19 augustus 2015 15:39:24 UTC+2 schreef Maarten Koopmans:

andrey mirtchovski

unread,
Aug 19, 2015, 10:18:53 AM8/19/15
to Maarten Koopmans, golang-nuts

If you're going to be using the struct in C then why not define it there in the first place and return that from the Go function?


--

Maarten Koopmans

unread,
Aug 19, 2015, 10:57:06 AM8/19/15
to golang-nuts, maarten....@gmail.com
I'md be defining the struct in a non-C language using libffi - and obviouslyy pretty new at this. Can this even be done?

The idea is that said language could greatly benefit from some os Go's crossplatform native code (a Lisp dialect that is really good at symbolic mainpulation, so I'd get the best of both worlds).


Op woensdag 19 augustus 2015 16:18:53 UTC+2 schreef andrey mirtchovski:

Ian Lance Taylor

unread,
Aug 19, 2015, 12:32:08 PM8/19/15
to Maarten Koopmans, golang-nuts
On Wed, Aug 19, 2015 at 7:05 AM, Maarten Koopmans
<maarten....@gmail.com> wrote:
>
> Pffff. I have a really hard time returning a struct that holds the buffer
> and the length.

What problems are you having?

> Given the above playground, is there a way to retrun structs from Go -> C?

Here is an example: http://play.golang.org/p/irjBR5o0kj .

Ian

Maarten Koopmans

unread,
Aug 19, 2015, 1:09:54 PM8/19/15
to Ian Lance Taylor, golang-nuts
That's not quite what I need. I want to call a function with parameters via libffi, and then get multiple values back. E.g. pass in byte array pointer, length. Get back processed byte array with length.

--Maarten  

Ian Lance Taylor

unread,
Aug 19, 2015, 2:20:12 PM8/19/15
to Maarten Koopmans, golang-nuts
On Wed, Aug 19, 2015 at 10:09 AM, Maarten Koopmans
<maarten....@gmail.com> wrote:
>
>
> Op woensdag 19 augustus 2015 heeft Ian Lance Taylor <ia...@golang.org> het
> volgende geschreven:
>>
>> On Wed, Aug 19, 2015 at 7:05 AM, Maarten Koopmans
>> <maarten....@gmail.com> wrote:
>> >
>> > Pffff. I have a really hard time returning a struct that holds the
>> > buffer
>> > and the length.
>>
>> What problems are you having?
>>
>> > Given the above playground, is there a way to retrun structs from Go ->
>> > C?
>>
>> Here is an example: http://play.golang.org/p/irjBR5o0kj .
>
>
> That's not quite what I need. I want to call a function with parameters via
> libffi, and then get multiple values back. E.g. pass in byte array pointer,
> length. Get back processed byte array with length.

Can you describe the problem you are having?

The Go code is going to have to have a struct definition, and that
struct ought to be defined in the C preamble. You can't create that
using libffi--that doesn't make sense, since the Go code has to return
a type declared in Go, whether via cgo or not. What you can do on the
libffi side is define a struct type and define the function as
returning that struct type. You can do that using the usual libffi
calls.

Where along this path are you running into trouble?

Ian

Ian Lance Taylor

unread,
Aug 19, 2015, 2:21:30 PM8/19/15
to Maarten Koopmans, golang-nuts
Is the problem that you are trying to use libffi to call a Go function
that returns multiple results? That won't work with the gc compiler
(you could make it work using gccgo). You will have to change the Go
function to return a single result, presumably a struct type.

Ian

andrey mirtchovski

unread,
Aug 19, 2015, 2:46:36 PM8/19/15
to Ian Lance Taylor, Maarten Koopmans, golang-nuts
> Is the problem that you are trying to use libffi to call a Go function
> that returns multiple results? That won't work with the gc compiler

isn't this exact scenario described in
https://golang.org/cmd/cgo/#hdr-C_references_to_Go?

e.g.,

//export MyFunction2
func MyFunction2(arg1, arg2 int, arg3 string) (int64, *C.char) {...}

is available in C as:

extern struct MyFunction2_return MyFunction2(int arg1, int arg2, GoString arg3);

or am I missing something?

Maarten Koopmans

unread,
Aug 19, 2015, 4:31:39 PM8/19/15
to andrey mirtchovski, Ian Lance Taylor, golang-nuts
I think that this:  https://golang.org/cmd/cgo/#hdr-C_references_to_Go?is what I want to. 

The fact that I use libffi was merely mentioned to give context. I try to write a go shared library where once we would have done that in C. 

I.e. Interpreter with libffi + Go shared library for NaCL, hashing, compression  etc.

Ian Lance Taylor

unread,
Aug 19, 2015, 4:43:08 PM8/19/15
to andrey mirtchovski, Maarten Koopmans, golang-nuts
I'm sorry, you're quite right. I entirely forgot about that.

Ian

Ian Lance Taylor

unread,
Aug 19, 2015, 4:43:48 PM8/19/15
to Maarten Koopmans, andrey mirtchovski, golang-nuts
On Wed, Aug 19, 2015 at 1:31 PM, Maarten Koopmans
<maarten....@gmail.com> wrote:
> I think that this: https://golang.org/cmd/cgo/#hdr-C_references_to_Go?is
> what I want to.

You're right. My apologies.

> The fact that I use libffi was merely mentioned to give context. I try to
> write a go shared library where once we would have done that in C.
>
> I.e. Interpreter with libffi + Go shared library for NaCL, hashing,
> compression etc.

I'm sorry, at this point I don't understand what you are asking. It
sounds like you understand what you need to do.

Ian

Maarten Koopmans

unread,
Aug 19, 2015, 5:49:04 PM8/19/15
to Ian Lance Taylor, andrey mirtchovski, golang-nuts


I'm sorry, at this point I don't understand what you are asking.  It
sounds like you understand what you need to do.

Indeed I do.

But think about this for a moment: Go is becoming the mainstream systems programming language with a set of libraries that is truly cross-platform.

The implications of a "libgo" with a lot of system oriented logic, callable via a C interface (libffi) in my case..... That will allow a lot of raw speed for interpreters of symbolic languages.

So on the one hand we have a very good "C" for the Internet age, but at the same time, it's an enabler for languages that are traditionally bad at systems stuff (often in important niches).

And to top it of children in the 12y range learn it easily.

Well done sirs, well done. 
Reply all
Reply to author
Forward
0 new messages