当前位置: 首页 > news >正文

Go 调用Rust函数

Go 调用Rust函数

在golang 中,go可以引用c代码,和c共舞,也就是cgo.在一些包里就能看到cgo的身影,gopcap(引用了libpcap),go-sqlite(引用了libsqlite).毕竟c是"万物之主"嘛.本文利用cgo实现go调rust函数

这是一个rust demo用于生成动态连接库for c

lib.rs 中的demo代码

#[no_mangle]
pub extern "C" fn say_hello(name:* const i8,age:std::ffi::c_int){let rname=unsafe{let realname=std::ffi::CStr::from_ptr(name);realname.to_str().expect("to string failed")};println!("hello {rname} your age is {age}");
}

cargo toml 添加此项生成动态库和静态库 for c.也可以二选一,没必要两个都编

[lib]
crate-type=["cdylib","staticlib"]

编译好后,只要引用了这个库就可以使用say_hello函数了.
go中引用say_hello代码

package main
//#cgo LDFLAGS: -L/Users/oswaldo/dev/rs/ffi/target/release -lffi
//extern void say_hello(const char*,int);
import "C"func main(){C.say_hello(C.CString("jim"),C.int(210))
}

运行看看效果

请添加图片描述

传个结构体交流交流

Go

package main//#cgo LDFLAGS: -L/Users/oswaldo/dev/rs/ffi/target/release -lffi
//#include <stdint.h>
//struct Student{uint8_t Age;uint8_t Score;uint16_t ID;};
//extern void say_hello(const char*,int);
//extern void get_student_info(struct Student*info);
import "C"type Student struct {Age   uint8Score uint8ID    uint16
}func main() {C.say_hello(C.CString("jim"), C.int(210))var student = C.struct_Student{Age:   22,Score: 90,ID:    0x0111,}C.get_student_info(&student)
}

Rust
#[repr(C)]是灵魂,不然以rust的方式对齐,和c是错位的。这个宏告诉编译器这个结构体以c的方式对齐。go结构体内存对齐方式和c一致(这也是为什么在go中无论是调某些syscall,还是我自己写的c库,我敢放心大胆的把go中结构体指针直接传过去,只要我内存构造和c中一致就不会出问题)

#[no_mangle]
pub extern "C" fn say_hello(name: *const i8, age: std::ffi::c_int) {let rname = unsafe {let realname = std::ffi::CStr::from_ptr(name);realname.to_str().expect("to string failed")};println!("hello {rname} your age is {age}");
}
/// repr(C)是灵魂,不然以rust的方式对齐,和c是错位的。这个宏告诉编译器这个结构体以c的方式对齐。go结构体内存对齐方式和c一致
#[repr(C)]
pub struct Student {pub age: u8,pub score: u8,pub id: u16,
}
#[no_mangle]
pub extern "C" fn get_student_info(student: *mut Student) {unsafe {let stu = student.as_ref().unwrap();let level=match stu.score {0 ..= 20 =>"C",21..=70=>"B",_=>"A"};println!("id: {},score: {}, age: {}, level {level}", stu.id, stu.score, stu.age);}
}

运行看看效果

请添加图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 浅谈线性表——链表
  • AI编程简介
  • 【第69课】Java安全JWT攻防Swagger自动化算法签名密匙Druid未授权
  • java-Mybatis框架
  • MFC程序设计(一) MFC框架
  • 23种设计模式详细知识点(软件设计师)
  • 【工控】线扫相机小结
  • Linux编程:使用 CSV 与 UnQLite 进行数据存储的比较分析
  • Java中‘==’ 和 equals()的区别
  • GeoScene Pro教程(001):软件功能产品介绍
  • Win11配置Pytorch深度学习环境(GPU版本)
  • 鸿蒙HarmonyOS实战:IPC与RPC设备内进程通信
  • 【ROS2】launch启动文件:基础
  • pyyaml:Python 中的 YAML 处理大师
  • 【数学建模】TOPSIS法(优劣解距离法)
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • Apache Pulsar 2.1 重磅发布
  • Druid 在有赞的实践
  • Fundebug计费标准解释:事件数是如何定义的?
  • js递归,无限分级树形折叠菜单
  • JS函数式编程 数组部分风格 ES6版
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • nodejs实现webservice问题总结
  • PermissionScope Swift4 兼容问题
  • python学习笔记-类对象的信息
  • QQ浏览器x5内核的兼容性问题
  • Sequelize 中文文档 v4 - Getting started - 入门
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 测试开发系类之接口自动化测试
  • 对JS继承的一点思考
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 关于Java中分层中遇到的一些问题
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 小李飞刀:SQL题目刷起来!
  • 2017年360最后一道编程题
  • 如何正确理解,内页权重高于首页?
  • ​虚拟化系列介绍(十)
  • #pragma 指令
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (003)SlickEdit Unity的补全
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (zhuan) 一些RL的文献(及笔记)
  • (补充):java各种进制、原码、反码、补码和文本、图像、音频在计算机中的存储方式
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (四)stm32之通信协议
  • (五)IO流之ByteArrayInput/OutputStream
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级