CGo error : Cannot use GoCallback (type func(_Ctype_int, unsafe.Pointer)) as type *[0]byte in function argument

1,528 views
Skip to first unread message

Francesco Bochicchio

unread,
Jan 29, 2014, 9:27:46 AM1/29/14
to golan...@googlegroups.com
Hi all,

I'm trying to call a Go function from C using CGo. The function shall accept a char** argument. 
The following code exemplifies what I'm trying to do:

 
package main

//
// typedef void (*Callback)(int argnum, char **args   );
// void CallMe( Callback f ) { 
//      char *args[2] = { "Ciao", "mondo" };
//       f(2, args); 
//           
//}
import "C"
import "unsafe"

func GoCallback( argnum C.int, args unsafe.Pointer ) {
// Convert args and do stuff
}


func main() {
C.CallMe(GoCallback)
}


I get the following error :

Cannot use GoCallback (type func(_Ctype_int, unsafe.Pointer)) as type *[0]byte in function argument

How comes a C function pointer becomes  a *[0]byte ( which should translate to "pointer to a zero-length array of bytes" ) ??

P.S : Doing  C.CallMe(C.Callback(GoCallback)) gives the following error, which is less puzzling but does not explain much:

cannot convert GoCallback (type func(_Ctype_int, unsafe.Pointer)) to type C.Callback 


Thanks in advance for any help 

Ciao
--- 
FB

minux

unread,
Jan 29, 2014, 4:06:33 PM1/29/14
to Francesco Bochicchio, golang-nuts

you cannot pass a Go func to C function.

what you can do is exporting a Go function, and let a C function call it.

read golang.org/cmd/cgo for details.

Malcolm Smith

unread,
Jan 29, 2014, 5:41:43 PM1/29/14
to golan...@googlegroups.com
Correct, you can't pass a Go func to a C function.

But in cgo you get the same error if you pass a C function to a C function!

C.Mix_HookMusicFinished(C.musicFinished)
fails with "cannot use _Cfpvar_fp_musicFinished (type unsafe.Pointer) as type *[0]byte in function argument"

while
C.Mix_HookMusicFinished((*[0]byte)(C.musicFinished))
works fine.

So my question is also
How come a C function pointer becomes  a *[0]byte ?

Francesco Bochicchio

unread,
Jan 30, 2014, 7:48:01 AM1/30/14
to golan...@googlegroups.com, Francesco Bochicchio
 


Yes, I forgot to add the //export  directive ... which in turn forced me to put the C code in a separate file ... but at the
end it seems to work.

Thanks Again 

Francesco Bochicchio

unread,
Jan 30, 2014, 7:50:16 AM1/30/14
to golan...@googlegroups.com, Francesco Bochicchio

minux

unread,
Jan 30, 2014, 11:09:28 AM1/30/14
to Malcolm Smith, golang-nuts

unsupported C pointer types are translated to *[0]byte.

minux

unread,
Jan 30, 2014, 11:09:28 AM1/30/14
to Francesco Bochicchio, golang-nuts


On Jan 30, 2014 7:48 AM, "Francesco Bochicchio" <bief...@gmail.com> wrote:
> Yes, I forgot to add the //export  directive ... which in turn forced me to put the C code in a separate file ... but at the
> end it seems to work.

if your C code contains only tiny wrapper functions, you can still put in the same Go file and label them as static inline.

Malcolm Smith

unread,
Jan 30, 2014, 2:46:48 PM1/30/14
to golan...@googlegroups.com, Malcolm Smith


On Thursday, January 30, 2014 4:09:28 PM UTC, minux wrote:


unsupported C pointer types are translated to *[0]byte.

Right, so you are saying they are unsupported by Go, hence the need for the ugly (*[0]byte) type conversion. But as I am passing the C pointer type to a C function this doesn't matter and the code works.

minux

unread,
Jan 30, 2014, 3:48:55 PM1/30/14
to Malcolm Smith, golang-nuts

if you cast the C function pointer to *[0]byte then it could be passed to a C function that takes a function pointer.

the choice of *[0]byte is not arbitrary, it means the same as void * in C.

Malcolm Smith

unread,
Jan 30, 2014, 4:52:12 PM1/30/14
to golan...@googlegroups.com, Malcolm Smith


On Thursday, January 30, 2014 8:48:55 PM UTC, minux wrote:


 the choice of *[0]byte is not arbitrary, it means the same as void * in C.


Thanks, having to use (*[0]byte) was making me nervous, but if it means void * then it makes perfect sense. 
Reply all
Reply to author
Forward
0 new messages