cgo类型转换
目录
- Cgo总结(一)
- 1、基本转换
- 1.1 char —>byte
- 1.2 signed char—>int8
- 1.3 unsigned char---->uint8
- 1.4 short int ----->int16
- 1.5 short unsigned int ---->uint16
- 1.6 int —> int
- 1.7 unsigned int ----->uint32
- 1.8 long int —>int32 or int64
- 1.9 long unsigned int----->uint32 or uint64
- 2.0 long long int ----->int64
- 2.1 long long unsigned int —> uint64
- 2.2 float---->float32
- 2.3 double—>float64
- 2.5 void * ---->*
- 总结:
- 使用代码:
Cgo总结(一)
这篇文章的目的:
探究c的基本类型到go类型的转换怎样才能安全;下面是根据之间的转换做的测试
结论是:
坑真多,自己要小心点;运行速度还慢,能不用就尽量不用!
测试内容如下:
1、基本转换
C类型 | 调用方法 | Go类型 | 字节数(byte) | 数值范围 |
---|---|---|---|---|
char | C.char | byte | 1 | -128~127 |
signed char | C.schar | int8 | 1 | -128~127 |
unsigned char | C.uchar | uint8 | 1 | 0~255 |
short int | C.short | int16 | 2 | -32768~32767 |
short unsigned int | C.ushort | uint16 | 2 | 0~65535 |
int | C.int | int | 4 | -2147483648~2147483647 |
unsigned int | C.uint | uint32 | 4 | 0~4294967295 |
long int | C.long | int32 or int64 | 4 | -2147483648~2147483647 |
long unsigned int | C.ulong uint32 or uint64 | 4 | 0~4294967295 | |
long long int | C.longlong | int64 | 8 | -9223372036854776001~9223372036854775999 |
long long unsigned int | C.ulonglong | uint64 | 8 | 0~18446744073709552000 |
float | C.float | float32 | 4 | -3.4E-38~3.4E+38 |
double | C.double | float64 | 8 | 1.7E-308~1.7E+308 |
wchar_t | C.wchar_t | wchar_t | 2 | 0~65535 |
void * | unsafe.Pointer |
1.1 char —>byte
package main
/*
#include<stdio.h>
char a = -128;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := byte(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
}
结果:
-128
类型为: main._Ctype_schar
128
类型为: uint8
代码2:
package main
/*
#include<stdio.h>
char a = -127;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := int8(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
}
结果为:
-127
类型为: main._Ctype_char
-127
类型为: int8
由上面看出byte 跟uint8的功能一样,问题是为啥有byte的存在呢?
1.2 signed char—>int8
package main
/*
#include<stdio.h>
signed char a = 12;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := byte(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
}
结果:
12
类型为: main._Ctype_schar
12
类型为: uint8
1.3 unsigned char---->uint8
package main
/*
#include<stdio.h>
unsigned char a = 254;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := byte(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
}
结果为:
254
类型为: main._Ctype_uchar
254
类型为: uint8
1.4 short int ----->int16
package main
/*
#include<stdio.h>
short a = -32768;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := int16(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
}
结果:
-32768
类型为: main._Ctype_short
-32768
类型为: int16
1.5 short unsigned int ---->uint16
package main
/*
#include<stdio.h>
short unsigned int a = 65535;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := uint16(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
}
结果:
65535
类型为: main._Ctype_ushort
65535
类型为: uint16
1.6 int —> int
package main
/*
#include<stdio.h>
int a = -2147483648;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := int(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
}
结果为:
-2147483648
类型为: main._Ctype_int
-2147483648
类型为: int
1.7 unsigned int ----->uint32
package main
/*
#include<stdio.h>
unsigned int a = 4294967295;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := uint32(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
}
结果:
4294967295
类型为: main._Ctype_uint
4294967295
类型为: uint32
1.8 long int —>int32 or int64
package main
/*
#include<stdio.h>
long int a = 2147483647;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := uint32(C.a)
c := uint64(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
fmt.Println(c)
fmt.Println("类型为:",reflect.TypeOf(c))
}
结果:
2147483647
类型为: main._Ctype_long
2147483647
类型为: uint32
2147483647
类型为: uint64
1.9 long unsigned int----->uint32 or uint64
package main
/*
#include<stdio.h>
long unsigned int a = 4294967295;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := uint32(C.a)
c := uint64(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
fmt.Println(c)
fmt.Println("类型为:",reflect.TypeOf(c))
}
2.0 long long int ----->int64
package main
/*
#include<stdio.h>
long long int a = -9223372036854776001;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := int32(C.a)
c := int64(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
fmt.Println(c)
fmt.Println("类型为:",reflect.TypeOf(c))
}
结果:
9223372036854775615
类型为: main._Ctype_longlong
-193
类型为: int32
9223372036854775615
类型为: int64
只有int64能接收到
2.1 long long unsigned int —> uint64
package main
/*
#include<stdio.h>
long long unsigned int a = -9223372036854776001;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := uint32(C.a)
c := uint64(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
fmt.Println(c)
fmt.Println("类型为:",reflect.TypeOf(c))
}
结果为:
9223372036854775615
类型为: main._Ctype_ulonglong
4294967103
类型为: uint32
9223372036854775615
类型为: uint64
只有uint64能接收到
2.2 float---->float32
package main
/*
#include<stdio.h>
float a = -3.14;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := float32(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
}
结果为:
类型为: main._Ctype_float
-3.14
类型为: float32
2.3 double—>float64
package main
/*
#include<stdio.h>
double a = -3.14159267333333333333333;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
b := float32(C.a)
c := float64(C.a)
fmt.Println(C.a)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
fmt.Println(c)
fmt.Println("类型为:",reflect.TypeOf(c))
}
结果为:
-3.1415926733333333
类型为: main._Ctype_double
-3.1415927
类型为: float32
-3.1415926733333333
类型为: float64
2.5 void * ---->*
package main
/*
#include<stdio.h>
int *a = 65535;
void *p =&a;
void printpoint(){
printf("point:%p\n",p);
}
*/
import "C"
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
b := unsafe.Pointer(C.p)
fmt.Println(C.p)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println(b)
fmt.Println("类型为:",reflect.TypeOf(b))
fmt.Println(C.printpoint())
}
结果:
0x53ec28
类型为: *main._Ctype_int
0x53ec28
类型为: unsafe.Pointer
[]
point:000000000053EC28
由以上看出从c到go的指针还是一样
总结:
在使用过程中转数据经常会造成数据不准的情况,查的时候特别费精力, 在 C 中的整形比如 int 在标准中是没有定义具体字长的,但一般默认是 4 字节,对应 CGO 类型中 C.int 则明确定义了字长是 4 ,但 golang 中的 int 字长则是 8 ,因此对应的 golang 类型不是 int 而是 int32 。为了避免go在调用C的时候还要考虑复杂的类型,建议使用 C99 标准的数值类型,对应的转换关系如下:
C语言类型 | CGO类型 | Go语言类型 |
---|---|---|
int8_t | C.int8_t | int8 |
uint8_t | C.uint8_t | uint8 |
int16_t | C.int16_t | int16 |
uint16_t | C.uint16_t | uint16 |
int32_t | C.int32_t | int32 |
uint32_t | C.uint32_t | uint32 |
int64_t | C.int64_t | int64 |
uint64_t | C.uint64_t | uint64 |
使用代码:
package main
/*
#include <stdint.h>
int8_t a = -128;
uint8_t b= 255;
int16_t c= -32768;
uint16_t d= 65535;
int32_t e = -2147483648;
uint32_t f = 4294967295;
int64_t g = -922337203685477601;
uint64_t h = 922337203685477599;
*/
import "C"
import (
"fmt"
"reflect"
)
func main() {
fmt.Println("---------------int8-------------")
a1 := int8(C.a)
fmt.Println(C.a)
fmt.Println(a1)
fmt.Println("类型为:",reflect.TypeOf(C.a))
fmt.Println("转后的类型:",reflect.TypeOf(a1))
fmt.Println("---------------uint8-------------")
b1 := uint8(C.b)
fmt.Println(C.b)
fmt.Println(b1)
fmt.Println("类型为:",reflect.TypeOf(C.b))
fmt.Println("转后的类型:",reflect.TypeOf(b1))
fmt.Println("---------------int16-------------")
c1 := int16(C.c)
fmt.Println(C.c)
fmt.Println(c1)
fmt.Println("类型为:",reflect.TypeOf(C.c))
fmt.Println("转后的类型:",reflect.TypeOf(c1))
fmt.Println("---------------uint16-------------")
d1 := uint16(C.d)
fmt.Println(C.d)
fmt.Println(d1)
fmt.Println("类型为:",reflect.TypeOf(C.d))
fmt.Println("转后的类型:",reflect.TypeOf(d1))
fmt.Println("---------------int32-------------")
e1 := int32(C.e)
fmt.Println(C.e)
fmt.Println(e1)
fmt.Println("类型为:",reflect.TypeOf(C.e))
fmt.Println("转后的类型:",reflect.TypeOf(e1))
fmt.Println("---------------uint32-------------")
f1 := uint32(C.f)
fmt.Println(C.f)
fmt.Println(f1)
fmt.Println("类型为:",reflect.TypeOf(C.f))
fmt.Println("转后的类型:",reflect.TypeOf(f1))
fmt.Println("---------------int64-------------")
g1 := int64(C.g)
fmt.Println(C.g)
fmt.Println(g1)
fmt.Println("类型为:",reflect.TypeOf(C.g))
fmt.Println("转后的类型:",reflect.TypeOf(g1))
fmt.Println("---------------uint64-------------")
h1 := uint64(C.h)
fmt.Println(C.h)
fmt.Println(h1)
fmt.Println("类型为:",reflect.TypeOf(C.h))
fmt.Println("转后的类型:",reflect.TypeOf(h1))
}