Skip to main content

C quick start for the Linux Barcode Scanner SDK

Build a lightweight barcode scanner in C for Linux. The command-line interface accepts a single image path as input, and the Scanbot SDK license key is embedded directly in the source code.

Install a C compiler, CMake and wget:

Install a C compiler, CMake, and wget

sudo apt update
sudo apt install -y cmake build-essential wget

Project layout

Create a minimal project.

mkdir -p barcode-quickstart-c && \
cd barcode-quickstart-c && \
touch CMakeLists.txt main.c

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include <ScanbotSDK.h>

// 👉 Replace this with your Scanbot SDK license key
static const char *SCANBOTSDK_LICENSE_KEY = "<SCANBOTSDK-LICENSE-KEY>";

/** Load an image from a file path using Scanbot SDK API. */
static scanbotsdk_error_code_t load_image_from_path(const char *path, scanbotsdk_image_t **out_image) {
scanbotsdk_path_image_load_options_t *options = NULL;
scanbotsdk_error_code_t ec = scanbotsdk_path_image_load_options_create_with_defaults(&options);
if (ec != SCANBOTSDK_OK) return ec;

ec = scanbotsdk_image_create_from_path(path, options, out_image);
scanbotsdk_path_image_load_options_free(options);
return ec;
}

/** Run the barcode scanner and print results. */
static scanbotsdk_error_code_t run_barcode_scanner(scanbotsdk_image_t *image) {
scanbotsdk_error_code_t ec = SCANBOTSDK_OK;

scanbotsdk_barcode_scanner_configuration_t *config = NULL;
scanbotsdk_barcode_scanner_t *scanner = NULL;
scanbotsdk_barcode_scanner_result_t *result = NULL;

// Create scanner config with defaults
ec = scanbotsdk_barcode_scanner_configuration_create_with_defaults(&config);
if (ec != SCANBOTSDK_OK) { fprintf(stderr, "config_create: %d\n", ec); goto cleanup; }

// Create scanner instance
ec = scanbotsdk_barcode_scanner_create(config, &scanner);
if (ec != SCANBOTSDK_OK) { fprintf(stderr, "scanner_create: %d\n", ec); goto cleanup; }

// Run scanner
ec = scanbotsdk_barcode_scanner_run(scanner, image, &result);
if (ec != SCANBOTSDK_OK) { fprintf(stderr, "scanner_run: %d\n", ec); goto cleanup; }

bool success = false;
scanbotsdk_barcode_scanner_result_get_success(result, &success);
if (!success) {
printf("No barcodes found.\n");
goto cleanup;
}

size_t count = 0;
ec = scanbotsdk_barcode_scanner_result_get_barcodes_size(result, &count);
if (ec != SCANBOTSDK_OK) { fprintf(stderr, "get_barcodes_size: %d\n", ec); goto cleanup; }

scanbotsdk_barcode_item_t **barcodes = calloc(count, sizeof(*barcodes));
if (!barcodes) { fprintf(stderr, "calloc failed\n"); ec = SCANBOTSDK_ERROR_OUT_OF_MEMORY; goto cleanup; }

ec = scanbotsdk_barcode_scanner_result_get_barcodes(result, barcodes, count);
if (ec != SCANBOTSDK_OK) { fprintf(stderr, "get_barcodes: %d\n", ec); goto cleanup; }

for (size_t i = 0; i < count; i++) {
const char *text = NULL;
scanbotsdk_barcode_item_get_text(barcodes[i], &text);
printf(" %zu) %s\n", i + 1, text ? text : "(null)");
}

free(barcodes);

cleanup:
scanbotsdk_barcode_scanner_result_free(result);
scanbotsdk_barcode_scanner_free(scanner);
scanbotsdk_barcode_scanner_configuration_free(config);
return ec;
}

int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <image_path>\n", argv[0]);
return 1;
}
const char *file_path = argv[1];

// Init SDK with license
scanbotsdk_init_params_t params = (scanbotsdk_init_params_t){0};
params.license_key = (char *)SCANBOTSDK_LICENSE_KEY;
params.writeable_path = ".";

scanbotsdk_error_code_t ec = scanbotsdk_initialize(&params);
if (ec != SCANBOTSDK_OK) { fprintf(stderr, "initialize: %d\n", ec); goto cleanup; }

// Load image and scan
scanbotsdk_image_t *image = NULL;
ec = load_image_from_path(file_path, &image);
if (ec != SCANBOTSDK_OK) { fprintf(stderr, "load_image_from_path: %d\n", ec); goto cleanup; }

ec = run_barcode_scanner(image);
if (ec != SCANBOTSDK_OK) { fprintf(stderr, "run_barcode_scanner: %d\n", ec); }

scanbotsdk_image_free(image);

cleanup:
return (ec == SCANBOTSDK_OK) ? 0 : 1;
}

CMakeLists

CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(scanbot_barcode_quickstart C)
set(CMAKE_C_STANDARD 11)

# Pass the SDK version like:
# cmake -DSCANBOTSDK_VERSION=<version> ..
if(NOT SCANBOTSDK_VERSION)
message(FATAL_ERROR "You must set -DSCANBOTSDK_VERSION=<version>")
endif()

# Where to extract and use the Scanbot SDK
set(SCANBOTSDK_DIR "${CMAKE_CURRENT_BINARY_DIR}/scanbotsdk" CACHE PATH "Scanbot SDK directory")

# --- Download & extract SDK if missing ---
if(NOT EXISTS "${SCANBOTSDK_DIR}/include" OR NOT EXISTS "${SCANBOTSDK_DIR}/lib")
find_program(WGET_PATH wget REQUIRED)
find_program(TAR_PATH tar REQUIRED)

# Detect architecture
if("${CMAKE_HOST_SYSTEM_PROCESSOR}" MATCHES ".*(arm|aarch64).*")
set(SCANBOTSDK_ARCHITECTURE "aarch64")
else()
set(SCANBOTSDK_ARCHITECTURE "x86_64")
endif()

set(TARBALL "scanbotsdk-${SCANBOTSDK_VERSION}-linux-${SCANBOTSDK_ARCHITECTURE}.tar.gz")
set(URL "https://github.com/doo/scanbot-sdk-example-linux/releases/download/standalone-sdk%2Fv${SCANBOTSDK_VERSION}/${TARBALL}")

message(STATUS "Downloading ${URL}")
execute_process(
COMMAND ${WGET_PATH} -q -O "${TARBALL}" "${URL}"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
RESULT_VARIABLE WGET_RES
)
if(NOT WGET_RES EQUAL 0)
message(FATAL_ERROR "Failed to download ${URL}")
endif()

# Extract directly into SCANBOTSDK_DIR (flatten with --strip-components=1)
file(MAKE_DIRECTORY "${SCANBOTSDK_DIR}")
execute_process(
COMMAND ${TAR_PATH} -xzf "${TARBALL}" -C "${SCANBOTSDK_DIR}" --strip-components=1
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
RESULT_VARIABLE TAR_RES
)
if(NOT TAR_RES EQUAL 0)
message(FATAL_ERROR "Failed to extract ${TARBALL}")
endif()
endif()

# --- Locate headers and libraries ---
find_library(ScanbotSDK_LIBS
NAMES scanbotsdk libscanbotsdk.so
HINTS ${SCANBOTSDK_DIR}/lib
)

find_path(ScanbotSDK_INCLUDE_DIRS
NAMES ScanbotSDK.h
HINTS ${SCANBOTSDK_DIR}/include
)

if(NOT ScanbotSDK_LIBS OR NOT ScanbotSDK_INCLUDE_DIRS)
message(FATAL_ERROR "Could not find Scanbot SDK inside ${SCANBOTSDK_DIR}")
endif()

# --- Import the SDK as a library target ---
add_library(scanbotsdk SHARED IMPORTED)
set_target_properties(scanbotsdk PROPERTIES
IMPORTED_LOCATION "${ScanbotSDK_LIBS}"
INTERFACE_INCLUDE_DIRECTORIES "${ScanbotSDK_INCLUDE_DIRS}"
)

# --- Build your app ---
add_executable(barcode-quickstart main.c)
target_link_libraries(barcode-quickstart scanbotsdk m pthread)

Build

# Create a build directory (keeps generated files separate from your source)
mkdir -p build
cd build

# Run CMake, passing the Scanbot SDK version and your API token
cmake -DSCANBOTSDK_VERSION=<SCANBOTSDK_VERSION> ..

# Compile the project
make -j

Run

Run the app with the path to an image file containing barcodes.

./barcode-quickstart /path/to/image_with_barcodes.jpg

🚀 That's it! You've built a minimal barcode scanner in C on Linux.

💡 In this quick start guide, we use the SDK's default scanner settings. However, you can freely customize the configuration, supported barcode types, and performance options.

Get in touch

If you need further information or are interested in licensing the Scanbot SDK, please get in touch with our solution experts.