Building Swift Barcode Reader with DBR 5.2 for Linux

Xiao Ling
4 min readOct 16, 2017

A few weeks ago, Apple released Swift 4.0 which is available for macOS and Ubuntu 14/16. In this post, I will share how to implement a simple Swift barcode reader (command line tool) with Dynamsoft Barcode Reader SDK for Linux.

Environment

Operating system and SDK

How to enable a shared folder in VMware

When using a virtual machine, a shared folder is handy if you want to use a Windows tool to write code for Linux.

It is easy to add a shared folder via virtual machine settings:

However, there may be no shared folder listed under /mnt/ in guest OS, such as Ubuntu 14.04. Run the following command to check Ubuntu version:

lsb_release -a

To solve the issue, download and install a patch:

git clone https://github.com/rasa/vmware-tools-patches.gitcd vmware-tools-patchessudo ./patched-open-vm-tools.shsudo vmware-config-tools.plsudo reboot

Now you can see the shared folder and files. This way is fine for running swift code as follows:

swift xxx.swift

Nevertheless, it will cause errors if you compiling the code with swiftc:

swiftc test.swift/usr/bin/ld.gold: fatal error: test: Input/output errorclang: error: linker command failed with exit code 1 (use -v to see invocation)<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)

How to solve swiftc issue: “<unknown>:0: error: link command failed with exit code 127 (use -v to see invocation)”

To use Swift, you have to install following dependencies beforehand:

sudo apt-get install clang libicu-dev

If you fail to run swiftc, please refer to Vincent Saluzzo’s solution:

sudo apt-get install -y libicu-devsudo apt-get install -y clang-3.6sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100

Creating Swift Barcode Reader with C library

Inspired by StackOverflow question — Compile C Code and Expose it to Swift under Linux, I have successfully created a command line barcode reader by linking libDynamsoftBarcodeReader.so.

Create dbr.h with some exposed methods:

#include "DynamsoftBarcodeReader.h"int initLicense(const char* pszLicense);char* decodeFile(const char* pFileName, int iFormat);int createDBR();void destroyDBR();

Create dbr.c to invoke Dynamsoft Barcode Reader SDK:

#include <stdio.h>#include "dbr.h"#define DBR_NO_MEMORY 0#define DBR_SUCCESS   1// Barcode reader handlervoid* hBarcode = NULL;/*** Create DBR instance*/int createDBR(){if (!hBarcode) {hBarcode = DBR_CreateInstance();if (!hBarcode){printf("Cannot allocate memory!\n");return DBR_NO_MEMORY;}}return DBR_SUCCESS;}/*** Destroy DBR instance*/void destroyDBR(){if (hBarcode) {DBR_DestroyInstance(hBarcode);}}/*** Set Dynamsoft Barcode Reader license.* To get valid license, please contact support@dynamsoft.com* Invalid license is acceptable. With an invalid license, SDK will return an imcomplete result.*/int initLicense(const char* pszLicense){if (!createDBR()){return -1;}return DBR_InitLicenseEx(hBarcode, pszLicense);}char* createPyResults(SBarcodeResultArray *pResults){// Get barcode resultsint count = pResults->iBarcodeCount;SBarcodeResult** ppBarcodes = pResults->ppBarcodes;SBarcodeResult* tmp = NULL;int i = 0;for (; i < count; i++){tmp = ppBarcodes[i];printf("Result: %s, Format: %s\n", tmp->pBarcodeData, tmp->pBarcodeFormatString);}// Release memoryDBR_FreeBarcodeResults(&pResults);return NULL;}/*** Decode barcode from a file*/char* decodeFile(const char* pFileName, int iFormat){if (!createDBR()){return NULL;}// Initialize Dynamsoft Barcode Readerint iMaxCount = 0x7FFFFFFF;SBarcodeResultArray *pResults = NULL;DBR_SetBarcodeFormats(hBarcode, iFormat);DBR_SetMaxBarcodesNumPerPage(hBarcode, iMaxCount);// Barcode detectionint ret = DBR_DecodeFileEx(hBarcode, pFileName, &pResults);// Wrap resultsreturn createPyResults(pResults);}

Create barcode.swift to call C APIs:

let count = CommandLine.arguments.countif count < 2 {print("Please add a file name. E.g. ./barcode test.tif")}else {let fileName = CommandLine.arguments[1]createDBR()let ret = initLicense("t0068MgAAAGvV3VqfqOzkuVGi7x/PFfZUQoUyJOakuduaSEoI2Pc8+kMwjrojxQgE5aJphmhagRmq/S9lppTkM4w3qCQezxk=")if ret == 0 {// Read barcodelet barcodeTypes : Int32 = 0x3FF | 0x2000000 | 0x8000000 |0x4000000;  // 1D, QRCODE, PDF417, DataMatrixdecodeFile(fileName, barcodeTypes);}destroyDBR()}

Compile dbr.c with gcc:

gcc -c dbr.c

Compile barcode.swift with swiftc:

swiftc -import-objc-header dbr.h barcode.swift dbr.o -o barcode -lDynamsoftBarcodeReader

Run the swift barcode reader:

./barcode test.tif

Source Code

https://github.com/dynamsoft-dbr/linux-swift-4.0-barcode-reader

Originally published at www.codepool.biz on October 16, 2017.

--

--

Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover