Rust Programming with Dynamsoft Barcode Reader

A few days ago, I accepted a new challenge of creating a simple command line barcode reader using Rust and Dynamsoft Barcode Reader SDK. Rust is a system programming language similar to C++. The learning process did not go through smoothly as I expected. It is not as easy as learning other high-level programming languages such as Java and Python. In this article, I share my experience of learning and using Rust.

Prerequisites

Building Rust Barcode Reader on Windows

Project initialization

Create a new project:

cargo new barcodereader

In main.rs, get the input file name from arguments:

Build and run the app:

cargo run .\images\AllSupportedBarcodeTypes.tif

Bridging Rust and native methods

To simplify the invoking process, create bridge.h and bridge.c.

// bridge.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);

To link the native library and build the bridge, create build.rs in the project root:

Add the configuration to Cargo.toml:

[package] 
# ...
build = "build.rs"
[build-dependencies] cc = "1.0"

Why not call native methods directly? It is complicated. If you do this, you have to define all C structures in Rust. The next step is to generate Rust FFI bindings based on the bridge.h file.

Converting C header files to Rust FFI bindings

Use bindgen to convert bridge.h to bridge.rs:

bindgen.exe --no-doc-comments --no-layout-tests bridge.h -o bridge.rs

When I ran the above command line the first time, I got the following error message:

error: toolchain 'stable-x86_64-pc-windows-msvc' does not have the binary `rustfmt.exe`

To fix the issue, install rustfmt-preview:

rustup component add rustfmt-preview

We can automate the process by adding bindgen as a build dependency in Cargo.toml:

[build-dependencies] 
bindgen = "0.42.1"

Then add the following code to build.rs:

Automatically copy *.dll files to the output directory after building the project

On Windows, we use .lib files for building projects and use .dll files for running apps. To make the program run, we have to copy DLL files to the output directory.

The first step is to get the path of the output folder:

Copy DLL files:

Here is the final build.rs:

Build and run Rust barcode reader

Call the barcode detection function in main.rs:

Build the app:

cargo build -vv

Clean the build:

cargo clean

Run the app:

cargo run <image file>

References

Source Code

https://github.com/yushulx/rust-barcode


Originally published at www.codepool.biz on October 11, 2018.