rust如何在木板上上传图片_C调用Rust动态链接库实现Http文件上传
絮絮叨叨
笔者最近做一个项目,跟一个写C的小伙一起开发。笔者原本是用Java写服务端接口的,那个小伙用C写客户端。客户端某个功能需要图片到服务端的Http接口上。
而写C的小伙目前对Http这块还不熟,加上C发起Http请求比较麻烦。于是笔者就想用Rust开发一个动态库链接库给C调用。在动态链接库公开一个函数,参数是Http的请求地址和图片,如果上传成功就返回1,失败就返回0。
Rust函数大致如下:
#[no_mangle]
pub extern "C" fn post_image(c_url: *const c_char, payload_ptr: *const payload_t) -> i32 {
// TODO
}
*const c_char用于接收来自C里面的字符串,在C里面对应的是const char *
*const payload_t是用来接收来自C的图片数据,在这里定应了一个Rust Struct
#[repr(C)]
pub struct payload_t {
data: *const u8,
len: c_int
}
这里的data表示接收一个来自C的指针,而len表示指针的长度。
下面来看整个扩展的编写过程。
开始写Rust代码
1、用cargo创建一个rust工程
cargo new mylib
cd mylib
2、在Cargo.toml文件中配置[lib]和[dependencies]
[lib]
name = "mylib"
crate-type = ["cdylib"]
path = "src/lib.rs"
[dependencies]
reqwest = {version = "0.10.0", features = ["blocking"] }
base64 = "0.11.0"
3、下面关键的步骤来了,编写lib.rs代码
use std::os::raw::{c_char, c_int};
use std::ffi::CStr;
use std::error::Error;
#[repr(C)]
pub struct payload_t {
data: *const u8,
len: c_int
}
#[no_mangle]
pub extern "C" fn post_image(c_url: *const c_char, payload_ptr: *const payload_t) -> i32 {
// 在这里开始一步步将c字符串转换成&str
let c_str: &CStr = unsafe {
CStr::from_ptr(c_url)
};
if let Err(err) = c_str.to_str() {
eprintln!("{}", err.description());
return 0;
}
let str_url = c_str.to_str().unwrap();
// 在这里开始将c传过来的文件,转换成&[u8]
let r_payload = unsafe {
*Box::from_raw(payload_ptr as *mut payload_t)
};
let bytes = unsafe {
std::slice::from_raw_parts(r_payload.data, r_payload.len as usize)
};
// 开始上传文件
if post(str_url, bytes) {
return 1;
}
return 0;
}
fn post(str_url: &str, payload: &[u8]) -> bool {
let client = reqwest::blocking::Client::new();
let body_base64 = base64::encode(payload);
if let Ok(res) = client.post(str_url).body(body_base64).send() {
let status = res.status();
println!("{:?}", res);
println!("{:?}", res.text());
if status == 201 {
return true;
}
};
return false;
}
在这里post函数中,把payload: &[u8]转为base64在上传的,实际不转也可以。主要得看接收文件的Http接口是如何做的。
用cbindgen生成头文件
1、安装cbindgen
cargo install --force cbindgen
2、在工程的根目录下编写cbindgen.toml文件
language = "C"
这里很简单,指定生成头文件的语言为C就可以了。这个文件为空也是可以的。
3、生成头文件
cbindgen --config cbindgen.toml --crate mylib --output mylib.h
编译动态链接库
cargo build
笔者用的是Mac系统,在target/debug目录下生成了libmylib.dylib文件,这个就是动态链接库了。接下来在这个目录下创建一个test.c文件来测试。
开始写C代码来测试
1、编写test.c
#include "mylib.h"
#include
int file_size(char * file_name)
{
FILE *fp = fopen(file_name, "rb");
int size;
if (fp == NULL)
return -1;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fclose(fp);
return size;
}
int main()
{
int size = 0;
const char *c_url = "http://localhost:8080/upload";
size = file_size("test.png");
FILE *fp;
char *buffer = (char*)malloc(sizeof(char)*size);
fp = fopen("test.png", "rb");
if (fp == NULL)
return 0;
fread(buffer, 1, size, fp);
fclose(fp);
payload_t payload;
payload_t *payload_ptr = malloc(sizeof(payload));
const uint8_t *buffer_ptr = (uint8_t *)buffer;
payload_ptr->data = buffer_ptr;
payload_ptr->len = size;
int32_t flag = post_image(c_url, payload_ptr);
if(flag == 1)
{
printf("%s\n", "上传成功");
}
else
{
printf("%s\n", "上传失败");
}
free(buffer);
buffer = NULL;
return 0;
}
这里是用C代码上传本地的一张test.png图片到服务端。测试时记得复制一张图片到C代码所在目录。
2、编译C,并运行
gcc test.c -L ./ -lmylib -o test
./test
mylib就是动态链接库的名称.
就这样结束了。
rust如何在木板上上传图片_C调用Rust动态链接库实现Http文件上传相关推荐
- 上传图片被防火墙拦截_Web安全:文件上传漏洞
文章来源:计算机与网络安全 一般将文件上传归类为直接文件上传与间接文件上传.直接文件上传就是服务器根本没有做任何安全过滤,导致攻击者可以直接上传小马文件及大马文件(如ASP.ASPX.PHP.JSP及 ...
- rust如何在木板上上传图片_腐蚀rust游戏玩法方式详解
在腐蚀这款游戏中玩家所有的物资都需要自己去寻找,不过很多时候遇到不怀好意的玩家时最好提高安全意识,及时躲避袭击,下面是游戏玩法发展方式详解. 游戏玩法方式详解 这里分两种发展方式 1.纯新手 首先需要 ...
- 服务器上传图片显示图片404,关于使用spring文件上传遇到的服务器中的图片访问不到报404的问题...
中的enctype确实是"multipart/form-data",后来实在没办法了,他前面提到过找不到类,那会不会是还有jar没有引进去呢,后来发现错误信息里有IOUtils这个 ...
- 微信小程序开发之文件上传下载应用场景(附Demo源码)
微信小程序开发之文件上传下载应用场景(附Demo源码),Demo为小相册应用,源码在附件中,本示例需要腾讯云支持. http://www.henkuai.com/forum.php?mod=viewt ...
- 文件上传、文件包含和目路遍历杂谈
一.说明 文件上传.文件包含和目路遍历是<黑客防线>盛行的时代常谈的getshell手法,但到现在的安全书藉感觉就比较少提及或一笔带过.在谈的年代看不懂,在看得懂的年代又不谈了,概念感觉总 ...
- multipart/form-data与httpclient文件上传
写在前面:本文讨论的内容都是基于java相关技术栈. 文件上传无论是在传统的基于html的web系统开发,还是目前主流的移动app开发,都是一个比较常见的功能需求.例如:web oa系统,可能会涉及到 ...
- django文件上传到服务器,django上传文件的三种方式
Django文件上传需要考虑的重要事项 文件或图片一般通过表单进行.用户在前端点击文件上传,然后以POST方式将数据和文件提交到服务器.服务器在接收到POST请求后需要将其存储在服务器上的某个地方.D ...
- 实现HTTP协议Get、Post和文件上传功能——使用WinHttp接口实现
在<使用WinHttp接口实现HTTP协议Get.Post和文件上传功能>一文中,我已经比较详细地讲解了如何使用WinHttp接口实现各种协议.在最近的代码梳理中,我觉得Post和文件上传 ...
- Struts 2的文件上传
Struts 2并未提供自己的请求解析器,也就是说,Struts 2不会自己去处理multipart/form-data的请求,它需要调用其他上传框架来解析二进制请求数据.但Struts 2在原有的上 ...
最新文章
- github创建本地库后关联远程库
- swoole php配置文件,easyswoole自义命令加载自定义配置文件
- 物联网技术概论的课程编号_选课推荐 | 第5期:物联网技术概论
- 杯子 + Kronican
- 遵义大数据中心项目工程概况_中策大数据:8月建筑工程项目有哪些?建筑工程项目信息汇总...
- R语言基础篇-----画图
- csredis封装_ASP.NET Core 2.0下使用Redis——基于CSRedis实现
- 时间序列-ARIMA模型调参检验实战
- Excel函数实战技巧精粹(二)常用函数之VLOOKUP全解
- LCD12864(ST7565P)字符汉字显示(STM32F103)
- dom影像图形成数字地形图_数字地形图等高线怎么生成(海地软件地形图数字化高层数据层怎么选择,在哪里...)...
- cad卸载不干净_如何才能干净的卸载顽固软件?不给恶意软件留机会!
- 倾斜摄影当中模型精度和测绘当中的分辨率/比例尺是怎么回事?
- 下列属于计算机应用,计算机的应用领域可大致分为6个方面,下列选项中属于计算机应用领域的是...
- asa 防火墙拦截了https_思科ASA防火墙下抓包方法
- linux c语言俄罗斯方块,C语言俄罗斯方块游戏解析(图文+源码)
- 使用matlab进行人工神经网络拟合
- Mornsun B0505S-1WR3 隔离模块DC/DC
- 租赁合同到期后如何处理
- debian squeeze安装Broadcom网卡驱动全程