Building a Cross-platform Command-line Barcode and QR Code Reader in C++

Dynamsoft Barcode Reader SDK v11, part of the Dynamsoft Capture Vision (DCV) framework, brings a major architectural upgrade for building barcode and QR code scanning applications on desktop, mobile, and web platforms. The v11 C++ SDK introduces the CCaptureVisionRouter as the central orchestration engine. As an enterprise-class C++ barcode and QR code scanning SDK, it supports Windows, Linux, macOS, Raspberry Pi, and Jetson Nano. This article helps developers build barcode and QR code reading applications in C++ using the new v11 API.

About Dynamsoft C++ Barcode and QR Code Reader SDK

SDK Download

v11.x

SDK License

Click here to get a 30-day free trial license. Initialize it before creating any capture vision router instance:

char szErrorMsg[256];
CLicenseManager::InitLicense("LICENSE-KEY", szErrorMsg, 256);

Note: CLicenseManager::InitLicense() must be called globally before creating a CCaptureVisionRouter instance.

A Command-line C++ Barcode and QR Code Reader for Multiple Platforms

To conveniently build our C++ application on different platforms, we create a CMake project. The v11 SDK ships as a unified DCV package under the dcv/ directory. In CMakeLists.txt, we configure include paths, library directories per platform, and link the necessary DCV modules — DynamsoftCore, DynamsoftLicense, DynamsoftCaptureVisionRouter, DynamsoftUtility, and DynamsoftBarcodeReader. C++17 is required:

cmake_minimum_required(VERSION 3.8)
project(main)

if(CMAKE_HOST_WIN32)
    set(WINDOWS 1)
elseif(CMAKE_HOST_APPLE)
    set(mac 1)
elseif(CMAKE_HOST_UNIX)
    set(LINUX 1)
endif()

# Require C++17
if(WINDOWS)
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
else()
    SET(CMAKE_CXX_FLAGS "-std=c++17 -O3 -Wl,-rpath=$ORIGIN")
endif()

MESSAGE(STATUS "CPU architecture ${CMAKE_SYSTEM_PROCESSOR}")
if(WINDOWS)
    link_directories("${PROJECT_SOURCE_DIR}/../../dcv/lib/win")
elseif(LINUX)
    if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
        link_directories("${PROJECT_SOURCE_DIR}/../../dcv/lib/linux/x64")
    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
        link_directories("${PROJECT_SOURCE_DIR}/../../dcv/lib/linux/arm64")
    endif()
elseif(mac)
    link_directories("${PROJECT_SOURCE_DIR}/../../dcv/lib/mac")
endif()

include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/../../dcv/include/")

add_executable(${PROJECT_NAME} main.cpp)

if(WINDOWS)
    target_link_libraries(${PROJECT_NAME}
        "DynamsoftCorex64" "DynamsoftLicensex64"
        "DynamsoftCaptureVisionRouterx64" "DynamsoftUtilityx64"
        "DynamsoftBarcodeReaderx64")
else()
    target_link_libraries(${PROJECT_NAME}
        "DynamsoftCore" "DynamsoftLicense"
        "DynamsoftCaptureVisionRouter" "DynamsoftUtility"
        "DynamsoftBarcodeReader" pthread)
endif()

Here are the C++ coding steps:

  1. Include the DCV v11 header files:

     #include "DynamsoftCaptureVisionRouter.h"
     #include "DynamsoftUtility.h"
    
     using namespace dynamsoft::license;
     using namespace dynamsoft::cvr;
     using namespace dynamsoft::dbr;
     using namespace dynamsoft::utility;
     using namespace dynamsoft::basic_structures;
    
  2. Initialize the license and create a CCaptureVisionRouter instance:

     char szErrorMsg[256];
     CLicenseManager::InitLicense("LICENSE-KEY", szErrorMsg, 256);
    
     CCaptureVisionRouter *cvr = new CCaptureVisionRouter;
    
  3. Decode barcodes from an image file (including multi-page TIFF/PDF):

     CCapturedResultArray *captureResultArray =
         cvr->CaptureMultiPages("image-file", CPresetTemplate::PT_READ_BARCODES);
    
  4. Iterate captured results per page and retrieve the barcode result:

     int count = captureResultArray->GetResultsCount();
     for (int i = 0; i < count; i++)
     {
         const CCapturedResult *result = captureResultArray->GetResult(i);
         if (result->GetErrorCode() != 0) continue;
    
         CDecodedBarcodesResult *barcodeResult = result->GetDecodedBarcodesResult();
         if (barcodeResult != nullptr && barcodeResult->GetErrorCode() == 0)
         {
             int itemCount = barcodeResult->GetItemsCount();
             cout << "Decoded " << itemCount << " barcodes" << endl;
             for (int j = 0; j < itemCount; j++)
             {
                 const CBarcodeResultItem *item = barcodeResult->GetItem(j);
                 cout << "Barcode Format: " << item->GetFormatString() << endl;
                 cout << "Barcode Text: "   << item->GetText() << endl;
             }
         }
         if (barcodeResult) barcodeResult->Release();
     }
     captureResultArray->Release();
    
  5. Release resources:

     delete cvr;
    

Build and Run

Windows (MSVC x64)

mkdir build
cd build
cmake -DCMAKE_GENERATOR_PLATFORM=x64 ..
cmake --build . --config release
.\release\main.exe [image-file-or-directory]

Linux / Raspberry Pi / Jetson Nano

mkdir build
cd build
cmake ..
cmake --build . --config release
./main [image-file-or-directory]

macOS

brew install cmake   # if not already installed
mkdir build
cd build
cmake ..
cmake --build . --config release
./main [image-file-or-directory]

The application supports both a single image file and a directory of images (JPG, PNG, BMP, TIFF, PDF). Run it without arguments to enter interactive mode.

C++ barcode QR code reader

Source Code

https://github.com/yushulx/cmake-cpp-barcode-qrcode-mrz/tree/main/examples/command-line