cgo unsigned char

2,103 views
Skip to first unread message

bemi

unread,
Jul 26, 2010, 8:42:38 PM7/26/10
to golang-nuts
Hello All,

Is cgo having problems recognizing unsigned char or I do something
wrong (I noticed this behavour when trying to compile uuid/uuid.h
header which comes with debian 'uuid-dev' package )?


This is my test code:

unsignedtest.h:
===========

#ifndef __unsignedtest_h
#define __unsignedtest_h

typedef unsigned char uarr[16];
typedef unsigned char uchar;

void fun (uarr in);
void fun1 (unsigned char *in);
void fun2 (uchar in);


#endif

unsignedtest.go:
============

package unsignedtest

/*
#include <unsignedtest.h>
*/
import "C"

func Fun() {
var in C.uarr
//var in1 *C.unsignedchar
var in2 C.uchar
C.fun(in)
//C.fun1(in1)
C.fun2(in2)
}

Compiling it I get errors:

CGOPKGPATH=unsignedtest /root/bin/cgo unsignedtest.go
/root/bin/8g -o _go_.8 unsignedtest.cgo1.go _cgo_gotypes.go
unsignedtest.cgo1.go:10: cannot use in (type _Ctypedef_uarr) as type
*_Ctype_unsignedchar in function argument
unsignedtest.cgo1.go:11: cannot use in2 (type _Ctype_unsignedchar) as
type _Ctypedef_uchar in function argument
make: *** [_go_.8] Error 1

_cgo_gotypes.go:
=============

// Created by cgo - DO NOT EDIT
package unsignedtest

import "unsafe"

import "os"

type _ unsafe.Pointer

func _Cerrno(dst *os.Error, x int) { *dst = os.Errno(x) }
type _Ctype_unsignedchar uint8
type _Ctypedef_uchar _Ctype_unsignedchar
type _Ctypedef_uarr [16]_Ctype_unsignedchar
type _Ctype_void [0]byte

func _Cfunc_fun(*_Ctype_unsignedchar)
func _Cfunc_fun2(_Ctypedef_uchar)

unsignedtest.cgo1.go
================

// Created by cgo - DO NOT EDIT
//line unsignedtest.go:1
package unsignedtest


func Fun() {
var in _Ctypedef_uarr

var in2 _Ctype_unsignedchar
_Cfunc_fun(in)
_Cfunc_fun2(in2)
}


The problem is with error on line 10. The only work around this error
I can think of is to do type conversion to '*C.unsignedchar' but when
I try it that type is not recognized (despite the fact that it is
defined in _cgo_gotypes.go).

How I would work around error on line 11 at all?, the diffrent way
uchar is translated when appears as variable declaration in block and
as function parameter declaration results in 2 different named types,
is there any reason for this?

Thanks in advance for any help with this,

Milan







Russ Cox

unread,
Jul 26, 2010, 9:37:51 PM7/26/10
to bemi, golang-nuts
You should be able to write C.uchar for
the C type "unsigned char" even without
the uchar typedef in your program.

The rest of the trouble has to do with the
different meanings between the C

void f(char x[20]);

and the Go

func f(x [20]byte)

The former is really the same as void f(char*),
and the latter is not. What function in libuuid
are you trying to call?

Russ

bemi

unread,
Jul 27, 2010, 1:06:33 PM7/27/10
to golang-nuts


On Jul 26, 6:37 pm, Russ Cox <r...@golang.org> wrote:
 What function in libuuid
> are you trying to call?
>
> Russ

I had troubles with this:

package libuuidtest

/*
#include <uuid/uuid.h>
*/
import "C"

func Uuid() {
var uuid C.uuid_t
C.uuid_generate(uuid)
}

Given your speedy reply following worked (is that correct approach?):

package libuuidtest


/*
#include <uuid/uuid.h>
*/
import "C"

import "unsafe"

func Uuid() {
var uuid C.uuid_t
C.uuid_generate((*C.uchar)(unsafe.Pointer(&uuid)))
}

I was confused looking into generated _cgo_gotypes.go, there I see for
unsigned char C.unsignedchar and that does not work. Where I can find
how C primitive types are to be referenced?, cgo command description
on web does not mention that for unsigned char I should use C.uchar.

Regards,
Milan

Russ Cox

unread,
Jul 27, 2010, 1:57:14 PM7/27/10
to bemi, golang-nuts
> Given your speedy reply following worked (is that correct approach?):

>        C.uuid_generate((*C.uchar)(unsafe.Pointer(&uuid)))

It's not ideal but for now, sure.
I'll take a look at whether cgo should be
doing a better job figuring out the type of
the function argument. C.uuid_generator(&uuid[0])
might work too.

> I was confused looking into generated _cgo_gotypes.go, there I see for
> unsigned char C.unsignedchar and that does not work. Where I can find
> how C primitive types are to be referenced?, cgo command description
> on web does not mention that for unsigned char I should use C.uchar.

I'll add it to the docs, but the list is:

var nameToC = map[string]string{
"schar": "signed char",
"uchar": "unsigned char",
"ushort": "unsigned short",
"uint": "unsigned int",
"ulong": "unsigned long",
"longlong": "long long",
"ulonglong": "unsigned long long",
}

(in addition to the usual char, short, int, long).

Russ

Reply all
Reply to author
Forward
0 new messages