Skip to content

Commit

Permalink
Added a Rust example
Browse files Browse the repository at this point in the history
  • Loading branch information
yushulx committed Jun 5, 2024
1 parent 61d3347 commit 45ab193
Show file tree
Hide file tree
Showing 10 changed files with 478 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ This repository contains examples demonstrating how to utilize the **Dynamsoft B
![Raspberry Pi barcode QR detection](https://www.dynamsoft.com/codepool/img/2020/06/raspberry-pi-barcode-qr.png)
- [Rust](./examples/9.x/rust/)
![Rust Barcode Reader](https://www.dynamsoft.com/codepool/img/2024/06/rust-command-line-barcode-reader.jpg)
## Blog
- [CMake: Build C++ Project for Windows, Linux and macOS](https://www.dynamsoft.com/codepool/cmake-cc-windows-linux-macos.html)
Expand Down
2 changes: 2 additions & 0 deletions examples/9.x/rust/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
**/*.rs.bk
118 changes: 118 additions & 0 deletions examples/9.x/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions examples/9.x/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "hello_world"
version = "0.1.0"
edition = "2018"

[build-dependencies]
cc = "1.0"
walkdir = "2.5.0"
28 changes: 28 additions & 0 deletions examples/9.x/rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Command-Line Barcode Reader in Rust
This project showcases a simple command-line barcode reader built using Rust and the Dynamsoft Barcode Reader SDK.

## Prequisites
- [Rust](https://www.rust-lang.org/tools/install)
- [Dynamsoft Barcode Reader Trial License](https://www.dynamsoft.com/customer/license/trialLicense/?product=dbr)

## Usage
1. Set the license key in `src/main.rs`:

```rust
let license = "LICENSE-KEY";
```

2. Clean and build the app:

```bash
cargo clean
cargo build
```

3. Run the app:

```bash
cargo run
```

![Rust Barcode Reader](https://www.dynamsoft.com/codepool/img/2024/06/rust-command-line-barcode-reader.jpg)
100 changes: 100 additions & 0 deletions examples/9.x/rust/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use std::env;
use cc::Build;

use std::fs;
use walkdir::WalkDir;
use std::path::{Path, PathBuf};

fn main() {
// Determine the target operating system
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
println!("cargo:warning=OS: {}..............................................", target_os);

match target_os.as_str() {
"windows" => {
// Link Dynamsoft Barcode Reader for Windows
println!("cargo:rustc-link-search=../../../platforms/win/lib");
println!("cargo:rustc-link-lib=static=DBRx64");

// Copy *.dll files to the output path for Windows
let src_dir = Path::new("../../../platforms/win/bin");
copy_shared_libs_from_dir_to_out_dir(src_dir, &get_out_dir(), "dll");
},
"linux" => {
// Link Dynamsoft Barcode Reader for Linux
println!("cargo:rustc-link-search=../../../platforms/linux");
println!("cargo:rustc-link-lib=dylib=DynamsoftBarcodeReader");

// Set rpath for Linux
println!("cargo:rustc-link-arg=-Wl,-rpath,../../../platforms/linux");

// Copy *.so files to the output path for Linux
let src_dir = Path::new("../../../platforms/linux/bin");
copy_shared_libs_from_dir_to_out_dir(src_dir, &get_out_dir(), "so");
},
"macos" => {
// Link Dynamsoft Barcode Reader for macOS
println!("cargo:rustc-link-search=../../../platforms/macos");
println!("cargo:rustc-link-lib=dylib=DynamsoftBarcodeReader");

// Set rpath for macOS
println!("cargo:rustc-link-arg=-Wl,-rpath,@loader_path/../../../platforms/macos");

// Copy *.dylib files to the output path for macOS
let src_dir = Path::new("../../../platforms/macos");
copy_shared_libs_from_dir_to_out_dir(src_dir, &get_out_dir(), "dylib");
},
_ => {
panic!("Unsupported target OS: {}", target_os);
}
}

// Compile the C++ code
Build::new()
.cpp(true)
.include("../../../include")
.file("lib/bridge.cpp")
.compile("bridge");

// Tell cargo to tell rustc to link the compiled C library
println!("cargo:rustc-link-lib=static=bridge");

// Add the directory where the library was built to the search path
println!("cargo:rustc-link-search=native={}", env::var("OUT_DIR").unwrap());
}

fn get_out_dir() -> PathBuf {
let out_dir = env::var("OUT_DIR").unwrap();
let debug_offset = out_dir.find("debug").unwrap_or(0);
let release_offset = out_dir.find("release").unwrap_or(0);
let mut path = String::from("");

if debug_offset > 0 {
println!(">>> where is debug {}", debug_offset);
path.push_str(&format!("{}", &out_dir[..debug_offset]));
path.push_str("debug");
println!("{}", path);
}

if release_offset > 0 {
println!(">>> where is release {}", release_offset);
path.push_str(&format!("{}", &out_dir[..release_offset]));
path.push_str("release");
println!("{}", path);
}

PathBuf::from(path)
}

fn copy_shared_libs_from_dir_to_out_dir(src_dir: &Path, out_dir: &Path, extension: &str) {
for entry in WalkDir::new(src_dir).into_iter().filter_map(|e| e.ok()) {
if entry.path().extension().and_then(|ext| ext.to_str()) == Some(extension) {
let lib_path = entry.path();
let file_name = lib_path.file_name().unwrap();
let dest_path = out_dir.join(file_name);

fs::copy(lib_path, dest_path.clone()).expect("Failed to copy shared library");
println!("Copied {} to {}", lib_path.display(), dest_path.display());
}
}
}
64 changes: 64 additions & 0 deletions examples/9.x/rust/lib/bridge.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "bridge.h"
#include <cstring>
#include <cstdlib>

Barcode *create_barcode(const char *type, const char *value, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
Barcode *barcode = (Barcode *)std::malloc(sizeof(Barcode));
barcode->barcode_type = strdup(type);
barcode->barcode_value = strdup(value);
barcode->x1 = x1;
barcode->y1 = y1;
barcode->x2 = x2;
barcode->y2 = y2;
barcode->x3 = x3;
barcode->y3 = y3;
barcode->x4 = x4;
barcode->y4 = y4;
return barcode;
}

void free_barcode(BarcodeResults *results)
{
for (int i = 0; i < results->count; i++)
{
std::free((void *)results->barcodes[i].barcode_type);
std::free((void *)results->barcodes[i].barcode_value);
}
std::free(results->barcodes);
std::free(results);
}

int init_license(const char *license)
{
char errorMsgBuffer[512];
// Click https://www.dynamsoft.com/customer/license/trialLicense/?product=dbr to get a trial license.
int ret = DBR_InitLicense(license, errorMsgBuffer, 512);
return ret;
}

BarcodeResults *decode_barcode_file(void *instance, const char *filename)
{
char errorMsgBuffer[512];
TextResultArray *pResults = NULL;
BarcodeResults *all_barcodes = NULL;
int ret = DBR_DecodeFile(instance, filename, "");
DBR_GetAllTextResults(instance, &pResults);
if (pResults->resultsCount > 0)
{
all_barcodes = (BarcodeResults *)std::malloc(sizeof(BarcodeResults));
all_barcodes->count = pResults->resultsCount;
all_barcodes->barcodes = (Barcode *)std::malloc(sizeof(Barcode) * pResults->resultsCount);
for (int iIndex = 0; iIndex < pResults->resultsCount; iIndex++)
{
LocalizationResult *localizationResult = pResults->results[iIndex]->localizationResult;
Barcode *barcode = create_barcode(pResults->results[iIndex]->barcodeFormatString, pResults->results[iIndex]->barcodeText,
localizationResult->x1, localizationResult->y1, localizationResult->x2, localizationResult->y2,
localizationResult->x3, localizationResult->y3, localizationResult->x4, localizationResult->y4);
all_barcodes->barcodes[iIndex] = *barcode;
}
}

DBR_FreeTextResults(&pResults);
return all_barcodes;
}
40 changes: 40 additions & 0 deletions examples/9.x/rust/lib/bridge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef BRIDGE_H
#define BRIDGE_H

#include "DynamsoftBarcodeReader.h"

#ifdef __cplusplus
extern "C"
{
#endif

typedef struct
{
const char *barcode_type;
const char *barcode_value;
int x1;
int y1;
int x2;
int y2;
int x3;
int y3;
int x4;
int y4;
} Barcode;

typedef struct
{
Barcode *barcodes;
int count;
} BarcodeResults;

Barcode *create_barcode(const char *type, const char *value, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
BarcodeResults *decode_barcode_file(void *instance, const char *filename);
void free_barcode(BarcodeResults *results);
int init_license(const char *license);

#ifdef __cplusplus
}
#endif

#endif // BRIDGE_H
Loading

0 comments on commit 45ab193

Please sign in to comment.