.NET Core Barcode Reader for Windows, Linux & macOS

.NET Core empowers C# developers to build DotNet applications for Windows, Linux, and macOS using one codebase. In this article, I want to share how to create a cross-platform .NET Core barcode app with Dynamsoft Barcode Reader SDK.

.NET Core barcode reader

.NET Core Installation

The latest .NET Core does not support the project.json files anymore. Instead, it uses MSBuild/csproj files for project configuration. If you have an old version installed and want to upgrade, you’d better read the article: A mapping between project.json and csproj properties.

C/C++ Barcode Libraries for Windows, Linux, and macOS

Get Dynamsoft C/C++ Barcode libraries.

.NET Core Barcode Reader

Create a new console project:

dotnet new console –o DynamsoftBarcode

The command line will generate two files: DynamsoftBarcode.csproj and Program.cs.

Copy shared libraries to the project root folder. To run the app, you have to copy *.dll, *.so, and *.dylib files to the output directory after building the project. Therefore, create an item group in DynamsoftBarcode.csproj file:

<ItemGroup>
    <None Update="DynamsoftBarcodeReader.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="libDynamsoftBarcodeReader.dylib">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="libDynamsoftBarcodeReader.so">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
</ItemGroup>

It is time to write some C# code in Program.cs.

To learn how to interoperate with native libraries, you can read the article - Native Interoperability. The technology used for accessing native structs and functions is called P/Invoke. Use the namespace System.Runtime.InteropServices to import shared libraries and define the corresponding native methods.

        [DllImport("DynamsoftBarcodeReader")]
        public static extern IntPtr DBR_CreateInstance();

        [DllImport("DynamsoftBarcodeReader")]
        public static extern void DBR_DestroyInstance(IntPtr hBarcode);

        [DllImport("DynamsoftBarcodeReader")]
        public static extern int DBR_InitLicense(IntPtr hBarcode, string license);

        [DllImport("DynamsoftBarcodeReader")]
        public static extern int DBR_DecodeFile(IntPtr hBarcode, string filename, string template);

        [DllImport("DynamsoftBarcodeReader")]
        public static extern int DBR_FreeTextResults(ref IntPtr pBarcodeResultArray);

        [DllImport("DynamsoftBarcodeReader")]
        public static extern void DBR_GetAllTextResults(IntPtr hBarcode, ref IntPtr pBarcodeResultArray);

        [DllImport("DynamsoftBarcodeReader")]
        public static extern int DBR_GetTemplateSettings(IntPtr hBarcode, string pszTemplateName, ref PublicParameterSettings pBarcodeResultArray);

        [DllImport("DynamsoftBarcodeReader")]
        public static extern int DBR_SetTemplateSettings(IntPtr hBarcode, string pszTemplateName, ref PublicParameterSettings pBarcodeResultArray, char[] szErrorMsgBuffer, int nErrorMsgBufferLen);

Invoking barcode APIs is not a big deal. The critical point is memory management – how to convert the managed structure to an unmanaged pointer and vice versa.

To pass a managed structure to an unmanaged pointer:

LinuxMacBarcodeManager.ReaderOptions ro = new LinuxMacBarcodeManager.ReaderOptions();
ro.llBarcodeFormat = iFormat;
ro.iMaxBarcodesNumPerPage = iMaxCount;

// Copy the struct to unmanaged memory.
IntPtr opt = Marshal.AllocHGlobal(Marshal.SizeOf(ro));
Marshal.StructureToPtr(ro, opt, false);

To get the final results, use Marshal.PtrToStructure:

if (pBarcodeResultArray != IntPtr.Zero)
                {
                    WinBarcodeManager.BarcodeResultArray results = (WinBarcodeManager.BarcodeResultArray)Marshal.PtrToStructure(pBarcodeResultArray, typeof(WinBarcodeManager.BarcodeResultArray));
                    int count = results.iBarcodeCount;
                    IntPtr[] barcodes = new IntPtr[count];
                    Marshal.Copy(results.ppBarcodes, barcodes, 0, count);

                    for (int i = 0; i < count; i++)
                    {
                        WinBarcodeManager.BarcodeResult result = (WinBarcodeManager.BarcodeResult)Marshal.PtrToStructure(barcodes[i], typeof(WinBarcodeManager.BarcodeResult));

                        Console.WriteLine("Value: " + result.pszBarcodeText);
                        Console.WriteLine("Format: " + result.pszBarcodeFormatString);
                        Console.WriteLine("-----------------------------");
                    }

                    // Release memory of barcode results
                    WinBarcodeManager.DBR_FreeTextResults(ref pBarcodeResultArray);
                }

That’s it. Try the sample code on Windows, Linux, and macOS.

dotnet restore
dotnet run

.NET Core bin

.NET Core barcode reader

Source Code

https://github.com/dynamsoft-dbr/dotnet-core-barcode

Search Blog Posts