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.