How to Build a Cross-Platform C++ Barcode and QR Code Reader with Dynamsoft Capture Vision v11

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.

What you’ll build: A CMake-based command-line C++ application that decodes barcodes and QR codes from image files and directories — including multi-page TIFFs and PDFs — running natively on Windows, Linux, macOS, Raspberry Pi, and Jetson Nano using Dynamsoft Capture Vision v11.

Key Takeaways

  • The Dynamsoft Capture Vision v11 C++ SDK replaces the older CBarcodeReader API with CCaptureVisionRouter as the central orchestration engine — all barcode decoding calls go through it.
  • CaptureMultiPages() handles single images, multi-page TIFFs, and PDFs in a single call with no per-format branching required.
  • The same CMake project compiles natively on Windows (MSVC x64), Linux x64/ARM64, macOS, Raspberry Pi, and NVIDIA Jetson Nano without any source code changes.
  • CLicenseManager::InitLicense() must be called globally before any CCaptureVisionRouter instance is created, or decoding will fail silently.

Common Developer Questions

How do I decode barcodes and QR codes from image files in C++ on Linux and Windows?

Create a C++ command-line tool that initializes the license, creates a CCaptureVisionRouter, and sends either a file path or a directory of images into the barcode-reading workflow. The same project layout works on both Linux and Windows, and the sample supports common image formats plus TIFF and PDF inputs.

How do I use Dynamsoft Capture Vision v11 with CMake on multiple platforms?

Set up one CMake project that switches library directories by platform and links the core DCV v11 modules, including DynamsoftCore, DynamsoftLicense, DynamsoftCaptureVisionRouter, DynamsoftUtility, and DynamsoftBarcodeReader. In v11, CCaptureVisionRouter replaces the older CBarcodeReader flow, so all decoding calls go through the new router API.

How do I read barcodes from a multi-page TIFF or PDF in C++?

Use CaptureMultiPages() instead of writing separate logic for each file type. That single call handles ordinary images, multi-page TIFFs, and PDFs, then returns per-page capture results you can iterate to extract barcode format and text.

About Dynamsoft C++ Barcode and QR Code Reader SDK

SDK Download

v11.x

SDK License

Get a 30-day free trial license to start building with the Dynamsoft C++ SDK. 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.

Build a Cross-Platform C++ Barcode and QR Code Reader

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;
    

Get your free 30-day trial license key and replace "LICENSE-KEY" above to run this against your own images.

Build and Run on Windows, Linux, macOS, and Raspberry Pi

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

Common Issues and Edge Cases

  • License not initialized before router creation: Calling new CCaptureVisionRouter before CLicenseManager::InitLicense() causes silent decoding failures. Always initialize the license globally as the very first step.
  • Missing shared libraries at runtime on Linux: If the executable can’t find .so files, either copy the libs from dcv/lib/linux/x64/ next to the binary or set LD_LIBRARY_PATH. The CMakeLists.txt already sets -Wl,-rpath=$ORIGIN to handle the co-located case automatically.
  • TIFF or PDF not decoded: Multi-page support requires DynamsoftUtility to be linked and its header included. If decoding silently returns zero results on a PDF, verify the link step and check that the file path contains no Unicode characters (use ASCII-only paths on Windows).

Download the Dynamsoft Capture Vision SDK and request a 30-day free trial license to integrate barcode and QR code decoding into your own C++ project.

Source Code

Get the complete sample project source code on GitHub