将c语言的结构体定义变成对应的golang语言的结构体定义,并将golang语言结构体变量的指针传递给c语言,cast C struct to Go struct
https://groups.google.com/forum/#!topic/golang-nuts/JkvR4dQy9t4
https://golang.org/misc/cgo/gmp/gmp.go
https://stackoverflow.com/questions/19910647/pass-struct-and-array-of-structs-to-c-function-from-go
https://studygolang.com/articles/6367
1、可以为c struct定义结构体函数,如下定义的打印函数,(你可能还可以定义改变结构体内部子field的函数,但我未验证过):
package main /*
struct CType {
int a;
char b;
float c;
};
*/
import "C" import "fmt" func (c _Ctype_struct_CType) String() string { return "hello" } func main() {
fmt.Printf("%v\n", C.struct_CType{})
}
其中的 _Ctype_struct_CType 寒气来有点奇怪,起始不用惊慌,可以用后面的方法自动得到这种奇怪的命名的。
当然,上面的只是演示为 c struct 定义内置函数。如果你仅仅是在golang中打印 c struct,只需要像普通变量一样直接传给Print就可以了,如: fmt.Printf("%v\n", C.objstruct) 或 fmt.Println(C.objstruct)。
2、你可以将整个golang的结构体指针转换成c语言的结构体指针,前提是golang 的结构体和c 的结构体定义是一一对应的(后面有介绍怎么穿件一一对应的结构体),但是c语言的结构体指针无法直接转换成golang语言的结构体指针:
You can cast the entire struct via intermediate pointers. The conversion should work in either direction. There are probably other ways too, like encoding/binary. An example of the pointer approach follows:
package main import (
"fmt"
"unsafe"
) // struct x {
// int y, z;
// };
//
// int sum(struct x a) {
// return a.y + a.z;
// }
//
import "C" type X struct{ Y, Z int32 } func main() {
a := &X{, }
fmt.Println(a, "->", C.sum(*((*C.struct_x)(unsafe.Pointer(a)))))
}
package main /*
#include <stdio.h>
*/
import "C" type File C.FILE
const Sizeof_File = C.sizeof_FILE
cgo -godefs 是专门用来将c语言结构体转换成golang语言对应的结构体的工具。
4、示例:
package main /*
#include <stdio.h> typedef struct {
int a;
int b;
} Foo; void pass_struct(Foo *in) { printf("%d : %d\n", in->a, in->b); } void pass_array(Foo **in, int len) {
for(int i = 0; i < len; i++) {
pass_struct(in[i]);
in[i]->a += 1;
in[i]->b += 1;
}
}
*/
import "C" import (
"fmt"
"unsafe"
) type Foo struct{ a, b int32 } func main() {
foo := Foo{, }
foos := []*Foo{&Foo{, }, &Foo{, }} fmt.Println("from C land")
C.pass_struct((*C.Foo)(unsafe.Pointer(&foo)))
C.pass_array((**C.Foo)(unsafe.Pointer(&foos[])), C.int(len(foos)))
fmt.Println("a & b should have incremented with 1") fmt.Println("from Go land")
for _, foo := range foos {
fmt.Printf("%d : %d\n", foo.a, foo.b)
}
}
Output:
from C land
:
:
:
a & b should have incremented with
from Go land
:
:
5、示例2:
将c语言的 char * 指针copy成 golang 的byte slice:
// convert c language char* to golang byte slice, and COPY source datas into dest slice
packet *C.char // 该变量在c语言里赋值
vlen :=
b := make([]byte, vlen)
ii := C.int()
for i := ; i < vlen; i++ {
ii = C.int(i)
// this is copy, not equal to the orignal pointer
b[i] = *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(packet)) + uintptr(unsafe.Pointer(C.int_to_charp(ii)))))
}
我自己的转换的示例:
c语言定义的结构体:
struct dnet_host {
struct dnet_key key;
char name[DNET_HOST_NAME_MAX];
char version[];
time_t last_active;
time_t last_appear;
time_t last_time_changed;
uint32_t crc32;
uint32_t route_ip;
unsigned name_len;
uint16_t route_port;
uint8_t is_local;
uint8_t is_trusted;
enum dnet_host_route_types route_type;
};
转成golang对应的结构体 (type DH C.struct_dnet_host):
type DH struct {
Key _Ctype_struct_dnet_key
Name []int8
Version []int8
Last_active int64
Last_appear int64
Last_time_changed int64
Crc32 uint32
Route_ip uint32
Name_len uint32
Route_port uint16
Is_local uint8
Is_trusted uint8
Route_type uint32
Pad_cgo_0 []byte
}
将c语言的结构体定义变成对应的golang语言的结构体定义,并将golang语言结构体变量的指针传递给c语言,cast C struct to Go struct的更多相关文章
- C语言基础知识点整理(函数/变量/常量/指针/数组/结构体)
函数 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ...
- C语言 指向结构体变量的指针
一个指向变量的指针表示的是占内存中起始位置 一个指向结构体的变量的指针表示的是这个结构体变量占内存中的起始位置,同样它也可以指向结构体变量数组 定义结构体变量的指针: //假设已有一个结构体名为Stu ...
- 你有对象类,我有结构体,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang结构体(struct)的使用EP06
再续前文,在面向对象层面,Python做到了超神:万物皆为对象,而Ruby,则干脆就是神:飞花摘叶皆可对象.二者都提供对象类操作以及继承的方式为面向对象张目,但Go lang显然有一些特立独行,因为它 ...
- 结构体struct sockaddr_in, struct sockaddr,struct in_addr
一.结构体 struct sockaddr_in, struct sockaddr, struct in_addr struct sockaddr_in, struct sockaddr,str ...
- 获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf
转载请注明出处:windeal专栏 Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq 结构体struct ifconf来获取网络接口的各种信息. ioctl 首先看 ...
- (转)类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET BCL里有哪些是类(结构),为什么它们不是结构(类)?在自定义类型时,您如何选择是类还是结构?
转自:http://blog.csdn.net/lingxyd_0/article/details/8695747 类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET B ...
- C/C++中指向结构体变量的指针,调用指向的那个结构体中的成员
设p是指向结构体变量的指针,则可以通过以下的方式,调用指向的那个结构体中的成员: (1)结构体变量.成员名.如,stu.num. (2)(*p).成员名.如,(*p).num. (3)p->成员 ...
- [转载]彻底弄清struct和typedef struct
struct和typedef struct 分三块来讲述: 1 首先://注意在C和C++里不同 在C中定义一个结构体类型要用typedef: typedef struct Student { int ...
- struct和typedef struct彻底明白了
struct和typedef struct 分三块来讲述: 1 首先://注意在C和C++里不同 在C中定义一个结构体类型要用typedef: typedef struct Student { int ...
随机推荐
- git 误删分支恢复方法
在使用Git的过程中,因为人为因素造成分支(commit)被删除,可以使用以下步骤进行恢复. 首先用以下步骤创建一个新分支,修改一些文件后删除,以便进行恢复. 1.创建分支 abc git branc ...
- Xamarin Mono Android实现“再按一次退出程序”
开始研究Android平台软件编程,Xamarin Mono for Android上手快,跨平台共享代码,代价是bug多多,是一味可口的毒药啊! 环境VS2012 + Xamarin Mono An ...
- TensorFlow—softmax_cross_entropy_with_logits函数详解
softmax_cross_entropy_with_logits函数原型: tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=pred ...
- day_5.28 py网络编程
端口 socket简介: socket为一个类 s接收的是返回的对象引用 2018-5-28 15:52:47 开始进行网络编程 udp 套接字 encode() 编码 decode() 解码 ' ...
- CodeForces - 754D
All our characters have hobbies. The same is true for Fedor. He enjoys shopping in the neighboring s ...
- Is char signed or unsigned by default? (转)
https://stackoverflow.com/questions/2054939/is-char-signed-or-unsigned-by-default
- 如何将MP3录音转文字
相信很多人都有电话录音的习惯,因为这样可以记录下很多重要的信息.那么当我们通过录音将一些重要的信息记录下来后,我们应该怎样将这些录音文件转换成文字进行记录呢?下面我们就一起来看一下吧. 操作步骤: 步 ...
- js积累点
window.opener.parent.frames['taskAnswerInfoForm'].location=newUrl;//可以使该frame的页面跳转.不需要再写xxx.location ...
- ubuntu汉化
寻找 Simplified Chinese,点击下面的apply 回到这里在最下面找到刚刚安装的语言,是灰色的,左键点击,将它拖到最上面,点击应用到整个系统,配置完成.重启系统就变成中文了. 晚上不要 ...
- [No000011E]Python教程1/9-Python简介
Python是一种计算机程序设计语言.你可能已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流行的Java语言,适合初学者的Basic语言,适合网页编程的JavaScript语言等等. 那P ...