2019独角兽企业重金招聘Python工程师标准>>>

最近看了下Rust,作为系统编程语言,真的是很复杂。我计划做一个简单的Rust模块,用于调用Dynamsoft Barcode Reader SDK,然后打包发布到https://crates.io/。

制作发布Rust Crate包

创建Rust lib工程:

cargo new dbr --lib

lib.rs中添加:

pub mod reader;

reader模块对应reader.rs文件,所以需要创建reader.h, reader.c

// reader.h
typedef struct Barcode {char* barcode_type;char* barcode_value;
} Barcode;typedef __int32 int32_t;
typedef void (*RustCallback)(int32_t, const char *, const char *);int32_t register_callback(RustCallback callback);
void c_decodeFile(const char *fileName, const char *pszLicense);
// reader.c
#include "reader.h"
#include "DynamsoftBarcodeReader.h"
#include <stdio.h>RustCallback cb;int32_t register_callback(RustCallback callback) {cb = callback;return 1;
}void c_decodeFile(const char *fileName, const char *pszLicense)
{void *hBarcode = DBR_CreateInstance();if (hBarcode){int ret = DBR_InitLicense(hBarcode, pszLicense);STextResultArray *paryResult = NULL;ret = DBR_DecodeFile(hBarcode, fileName, "");DBR_GetAllTextResults(hBarcode, &paryResult);int count = paryResult->nResultsCount;printf("Barcode found: %d\n", count);int i = 0;for (; i < count; i++){// printf("Index: %d, Barcode Type: %s, Value: %s\n", i, paryResult->ppResults[i]->pszBarcodeFormatString, paryResult->ppResults[i]->pszBarcodeText);if (cb) {cb(i, paryResult->ppResults[i]->pszBarcodeFormatString, paryResult->ppResults[i]->pszBarcodeText);}}DBR_FreeTextResults(&paryResult);DBR_DestroyInstance(hBarcode);}
}

接下来用bindgenreader.h转换成reader.rs

cargo install bindgen
bindgen src/reader.h -o src/reader.rs

在根目录创建build.rs用于构建工程。在构建的时候把.lib和.dll文件都拷贝到输出目录,然后把输出目录设置成库的查找路径:

extern crate cc;
extern crate bindgen;use std::env;
use std::fs;
use std::path::Path;fn main() {// Get the output pathlet out_dir = env::var("OUT_DIR").unwrap();let package_offset = out_dir.find("package").unwrap_or(0);if package_offset == 0 {// Generates Rust FFI bindings.let bindings = bindgen::Builder::default()// The input header we would like to generate// bindings for..header("src/reader.h")// Finish the builder and generate the bindings..generate()// Unwrap the Result and panic on failure..expect("Unable to generate bindings");bindings.write_to_file("src/reader.rs").expect("Couldn't write bindings!");}// Build C code.cc::Build::new().include("include").file("src/reader.c").compile("reader");// Copy *.dll & .lib to the output pathlet dll_src: String = String::from("./platforms/win/DynamsoftBarcodeReaderx64.dll");let dll_dest_path = Path::new(&out_dir).join("DynamsoftBarcodeReaderx64.dll");let _dll_result = fs::copy(dll_src, dll_dest_path);let lib_src: String = String::from("./platforms/win/DBRx64.lib");let lib_dest_path = Path::new(&out_dir).join("DBRx64.lib");let _lib_result = fs::copy(lib_src, lib_dest_path);// Link Dynamsoft Barcode Reader.// println!("cargo:rustc-link-search={}", env!("DBR_LIB"));println!("cargo:rustc-link-search={}", &out_dir);println!("cargo:rustc-link-lib=DBRx64");
}

上面的代码除了库的链接,还包括C代码的编译以及.h文件到.rs文件的转换。

Cargo.toml中添加依赖

[build-dependencies]
cc = "1.0"
bindgen = "0.42.1"

生成reader.rs:

cargo build

在打包前,记得把文件类型添加到Cargo.toml中:

include = ["**/*.lib","**/*.dll","**/*.rs","**/*.c","**/*.h","Cargo.toml",
][lib]
name = "dbr"
path = "src/lib.rs"

Crate打包:

cargo package

在https://crates.io/me生成token,通过命令行登录:

cargo login <token>

发布Crate包:

cargo publish

这里是我制作的dbr包:https://crates.io/crates/dbr

使用方法

创建一个新的Rust工程:

cargo new test

Cargo.toml中添加依赖:

[dependencies]
dbr = "0.1.3"

编辑main.rs:

extern crate dbr;use std::ffi::CStr;
use std::ffi::CString;
use std::os::raw::c_char;
use std::env;use dbr::reader::*;extern "C" fn callback(index: i32, barcode_type: *const c_char, barcode_value: *const c_char) {unsafe {println!("Index {}, {}, {}",index,CStr::from_ptr(barcode_type).to_str().unwrap(),CStr::from_ptr(barcode_value).to_str().unwrap());}
}fn main() {let args: Vec<String> = env::args().collect();if args.len() == 1 {println!("Please input an image file.");return}println!("Hello Dynamsoft Barcode Reader!");unsafe {register_callback(Some(callback));let image_file = CString::new(env::args().nth(1).expect("Missing argument")).unwrap();let license = CString::new("t0068NQAAAFKYHV9xSZDEThUtClXNzxXH9TLSj/vYcY8mSKa0RxaGw3qNynyAMJ9Ib8UPxzFsbAMIugqPO313BvfiOdmZFTY=").unwrap();c_decodeFile(image_file.as_ptr(), license.as_ptr());}println!("Bye!");
}

运行程序:

cargo run <image file>

源码

https://github.com/dynamsoft-dbr/rust

转载于:https://my.oschina.net/yushulx/blog/2247954

如何在Windows上制作一个包含.lib和.dll的Rust Crate包相关推荐

  1. 如何在Linux上制作一个屏幕录像视频教程

    一图胜千言,一个精心设计的指导视频更是能给你带来良好体验.Linux上有你需要的制作有用且高质量教学视频的所有工具.我们将用强大的kdenlive视频编辑器和Audacity音频录制器和编辑器制作一个 ...

  2. 【新手教程】如何在Win11上制作一个模仿MacOS的桌面?

    起因是早上蹲坑的时候偶然间在小红书上刷到一篇文章,看了下效果图感觉还不错,所以按照文章作者的流程来了一遍.过程中也遇到了一些小问题,正好放假了有空就写一篇文章记录一下.先放一下效果: 1. 创建下方D ...

  3. 【腾讯云 Finops Crane 集训营】 如何在Windows上快速搭建一个Kubernetes+Crane 环境及应用

    一.前言 个人主页: ζ小菜鸡 大家好我是ζ小菜鸡,让我们一起学习在 Windows 如何快速搭建一个Kubernetes+Crane 环境及应用. 如果文章对你有帮助.欢迎关注.点赞.收藏(一键三连 ...

  4. Windows的启动u盘linux,如何在linux下制作一个windows的可启动u盘?

    如何在linux下制作一个windows的可启动u盘? 情景是这样的,有一个windows10的iso,现在想通过U盘安装,要求即支持UEFI(启动引导器),又支持Legacy(启动引导器),因为有一 ...

  5. 如何在Windows上使用Git创建一个可执行脚本?

    长话短说,今天介绍如何在windows上使用Git上创建一个可执行的shell脚本. " 首先我们要知道windows上Git默认添加的文件权限是:-rw-r--r--(对应权限值是644) ...

  6. 如何在Windows上运行Redis?

    如何在Windows上运行Redis? Redis下载页面似乎只提供* nix选项. 我可以在Windows上本地运行Redis吗? #1楼 MS Open Tech最近提供了Redis版本,可以在G ...

  7. java 中window_教你如何在windows上安装Java

    最近够倒霉的,电脑硬盘坏了,重新做了个系统,各种环境全都没了,/(ㄒoㄒ)/~~ 然后我发现自己在重新安装各种环境的时候,有些东西竟然还需要去查,所以决定把这些环境的配置都写成博客记录下来. 今天就教 ...

  8. 如何在windows上搭建mysql_如何在Windows上安装多个MySQL

    [IT168 技术文档]本文以免安装版的mysql(Without installer)为例,对如何在Windows上安装多个MySQL进行讲解. 免安装版的mysql(Without install ...

  9. mongodb卸载_如何在Windows上安装MongoDB,启动,卸载

    mongodb卸载 Today we will learn how to install MongoDB on Windows. Most of us use Windows for our pers ...

  10. windows 安装php_如何在Windows上安装PHP

    windows 安装php We've previously shown you how to get a working local installation of Apache on your W ...

最新文章

  1. 奇葩错误:不同变量名称相同
  2. Java五年,已财富自由,美人在手!
  3. 企业网站标题优化要学会运用技巧和方法
  4. (转)【javascript基础】原型与原型链
  5. Fcoin Token ( FT )——数字货币交易所的颠覆者,还是无情镰刀的收割者
  6. how to extend odata service
  7. jer中无html文件,index.html
  8. 生产企业如何部署VMware虚拟化的解决方案
  9. ubuntu16.04 gcc降级到4.8
  10. sql crud_SQL Server中的CRUD操作
  11. SAP Table 汇总版
  12. 一元线性回归(最小二乘法)
  13. 机房巨佬的随机名称生成器
  14. EXCEL:如何设置某一列不能修改
  15. 参加百度开放云编程马拉松后一点总结
  16. java实现手机扫描二维码下载功能
  17. 谨以此篇献给即将奔三十的人们
  18. ZZULIOJ1096-1100Python解法
  19. “文心CV大模型” - VIMER-UFO论文报告
  20. 系统分析与设计个人总结

热门文章

  1. Advanced DataStream API Low-latency Event Time Join
  2. PHP 安全检测代码片段
  3. arcgis开发笔记【silverlight 发布rest地图服务】
  4. spring整体架构
  5. DOS批处理中对含有特殊字符的文件名的处理方法
  6. Servlet JSP - 转发与重定向的区别
  7. can't find which disk is full
  8. 2015上海网络赛 HDU 5475 An easy problem 线段树
  9. Unity for Windows: III–Publishing your unity game to Windows Phone Store
  10. 设置Excel单元格下拉列表的方法