NumXL Software Development Kit (SDK)
Getting Started

This section provides a clear, step-by-step guide for getting started with the NumXL SDK programming. It is designed to help you understand the basic functions and data structures, as well as how they work together.

Important: This tutorial focuses on development configuration using Visual Studio for C/C++ development. However, if you are using a different development tool, you can adapt the steps to align with the user interface of your chosen tool.

Creating Your Application

To start using NumXL in your C/C++ project, follow these steps:

  1. Add the "numxl.sdk.c" NuGet package to your project.
  2. Obtain a license key and activate it on your machine.
  3. Initialize the SDK modules.
  4. Begin programming.
  5. Build, debug, and run your program.

Note: The NumXL SDK package includes scripts that automatically append the necessary settings to your build environment, specifically for the compiler and linker. Additionally, it copies platform-specific runtime files, such as DLLs, into your project's output folder. This means you don't need to modify your project settings in order to build or run your application.

1. Adding the NumXL SDK package

The NumXL SDK package includes scripts that automatically append the necessary settings to your build environment, specifically for the compiler and linker. Additionally, it copies platform-specific runtime files, such as DLLs, into your project's output folder. You don't need to modify your project settings to build or run your application.

Refer to Installation page for a step-by-step guide on adding numxl.sdk.c using the NuGet Package Manager Tool in Visual Studio Studio.

2. Acquiring and activating License key

To use the NumXL SDK functions, you must obtain a license key by either requesting a free 14-day trial or purchasing a paid subscription on our website.

The license key is a text string formatted like "79F7-C8-ZZ-XX-YYYY," where X, Y, and Z represent hexadecimal digits.

After adding the NumXL SDK NuGet package to your project, the package will copy the necessary NumXL runtime files to your project's output directory. This includes a command-line utility called sflmgr.exe. You can use this utility to request a trial license key, activate the license on your machine, and generate the activation code.

Refer to License Key & Activation page for a detailed guide on requesting a trial license key and generating the activation code using the sflmgr.exe utility.

Note: Please remember that the license key and activation code remain unchanged until the next subscription renewal date. You should store them in a permanent form(e.g., file, registry) so your application can retrieve them for the SDK initialization.

3. Initializing the SDK

The NumXL SDK comprises five separate modules:

  • Logging Module (SFLOG) - Optional
  • Licensing Module (SFLUC) - Required
  • Locality Module (SFMSG) - Optional
  • Date and Calendar Module (SFDBM) - Optional
  • Analytics Module (SFSDK) - Required

Each module is initialized by invoking the configuration API (*_INIT(.)), where operation parameters can be set.

std::wstring szAppName = L"testapp";
std::wstring szLogDir =L"C:\\temp";
DWORD dwBackupFiles=7;
size_t ulMaxFileSize= (1024 * 1024); // 1 MB
unsigned int uLOGToken=0;
int nRetCode = SFLOG_INITW(szAppName.c_str(),szLogDir.c_str(), dwBackupFiles, ulMaxFileSize,&uLOGToken);
if(nRetCode == NDK_SUCCESS){
std::cout << " SUCCESS - Logging system is initialized .." << std::endl;
// 2 - Initialize the license system
unsigned uLUCToken=unsigned(-1);
std::wstring szProdKey(L"31223-200-169"); // NumXL 1.69
std::wstring szLicenseKey(L"79F7-C8-A9-01-7777");
std::wstring szActivationCode(L"2c07d642fe1ef089e5517d35e15f186814e17fb80b25cd950e77ade2e63c82c65d94ca6"
"39a77475d11981fd0a06e3ece730ef09c53c1f2da6d89d9a1d453d5e3678e50786a4210"
"1f194ffd543c2b72b55576fa52796acfd42ea715e132abddbc0877a5d0ba9e071c5639d"
"1cb9567d49c8019ef86549321c577193f0cd6ecba852013730ccda7f9d3b25dd6b10ffc"
"a6628835c52f4c4775d3cc295d814b542abe370abac97a2b71c5949736d7c007442b956"
"deac50bdcff423e4b2304e7153fffc61d5a15361ada3444e67075f09f15a4eefaf1d671"
"0d9e4e44b6adbf175caeb3446c64ead56333c8c0df6a487b549ec2b9bf5d733edbc062ce874986caf63756");
// Important: Replace the value of the license and activation code with your license key and the corresponding generated activation code
nRetCode = SFLUC_INIT( szProdKey.c_str(), szLicenseKey.c_str(),szActivationCode.c_str(), &uLUCToken);
if(nRetCode == NDK_SUCCESS){
std::wcout << L" SUCCESS - License system is initialized" << std::endl;
// 3- Initialize the SDK system
unsigned int m_uSDKToken = unsigned(-1);
nRetCode = NDK_Init(szAppName.c_str(), NULL/*Temp Data Directory*/, 0L /*Timeout = default*/, &m_uSDKToken);
if(nRetCode == NDK_SUCCESS){
std::wcout << L" SUCCESS - Analytics SDK system is initialized" << std::endl;

In most cases, your application doesn't need to initialize all five modules. However, it should at least initialize the SFLUC module and one or more additional modules, such as SFSDK, from which it calls corresponding functions.

The SDK initialization shoudl be made early during application startup, and a clean-up code before your process exits. If you are building a libray (DLL), then you initialize the SDK before calling any of its function.

Notice: There are few functions in SFLUC that don't require library initialization (e.g., SFLUC_MACHINEID), but for the vast majority, they will fail if you were to call them before their corresponding module is initialized.

4. Call the functions

Once you initialize the sdk modules, you are ready to call the different functions and pass your data for processing.

In the example below, we show running simple exponential smoothing (Brown's) on the international airline passenger data:

double airline_data[156]={
112,118,132,129,121,135,148,148,136,119,104,118,
115,126,141,135,125,149,170,170,158,133,114,140,
145,150,178,163,172,178,199,199,184,162,146,166,
171,180,193,181,183,218,230,242,209,191,172,194,
196,196,236,235,229,243,264,272,237,211,180,201,
204,188,235,227,234,264,302,293,259,229,203,229,
242,233,267,269,270,315,364,347,312,274,237,278,
284,277,317,313,318,374,413,405,355,306,271,306,
315,301,356,348,355,422,465,467,404,347,305,336,
340,318,362,348,363,435,491,505,404,359,310,337,
360,342,406,396,420,472,548,559,463,407,362,405,
417,391,419,461,472,535,622,606,508,461,390,432,
444,416,472,499,497,579,667,657,557,492,425,481};
double alpha=0.3;
double retVal=0.0;
nRetCode = NDK_SESMTH(airline_data, 156, TRUE, &alpha, 1, TRUE, NULL, 0, &retVal);
if( nRetCode == NDK_SUCCESS){
// The SESMTH 1-step forecast is
std::wcout << L" SUCCESS - SESMTH returns: " << retVal << std::endl;

4. Shutdown the SDK

Before the application process shutdown, you must call the shutdown functions in the sdk:

NDK_Shutdown(TRUE, m_uSDKToken);
}
}
SFLUC_SHUTDOWN(uLUCToken);
}
std::cout << " Shutting down the Logging system ..." << std::endl;
SFLOG_SHUTDOWN(uLOGToken);
Remarks
  1. The NumXL SDK exports its functions using C-API interface.
  2. The SDK functions don't pass any exceptions to the caller application.
  3. The SDK functions report its status via error codes expressed as a return value.
Example
#include <windows.h>
#include <iostream>
#include <string>
#include "SFLOG.h"
#include "SFLUC.h"
#include "SFSDK.h"
int main(){
// 1 - INityialize the logging system (for internal use)
std::wstring szAppName = L"testapp";
std::wstring szLogDir =L"C:\\temp";
DWORD dwBackupFiles=7;
size_t ulMaxFileSize= (1024 * 1024); // 1 MB
unsigned int uLOGToken=0;
int nRetCode = SFLOG_INITW(szAppName.c_str(),szLogDir.c_str(), dwBackupFiles, ulMaxFileSize,&uLOGToken);
if(nRetCode == NDK_SUCCESS){
std::cout << " SUCCESS - Logging system is initialized .." << std::endl;
// 2 - Initialize the license system
unsigned uLUCToken=unsigned(-1);
std::wstring szProdKey(L"31223-200-169"); // NumXL 1.69
std::wstring szLicenseKey(L"79F7-C8-A9-01-7777");
std::wstring szActivationCode(L"2c07d642fe1ef089e5517d35e15f186814e17fb80b25cd950e77ade2e63c82c65d94ca6"
"39a77475d11981fd0a06e3ece730ef09c53c1f2da6d89d9a1d453d5e3678e50786a4210"
"1f194ffd543c2b72b55576fa52796acfd42ea715e132abddbc0877a5d0ba9e071c5639d"
"1cb9567d49c8019ef86549321c577193f0cd6ecba852013730ccda7f9d3b25dd6b10ffc"
"a6628835c52f4c4775d3cc295d814b542abe370abac97a2b71c5949736d7c007442b956"
"deac50bdcff423e4b2304e7153fffc61d5a15361ada3444e67075f09f15a4eefaf1d671"
"0d9e4e44b6adbf175caeb3446c64ead56333c8c0df6a487b549ec2b9bf5d733edbc062ce874986caf63756");
// Important: Replace the value of the license and activation code with your license key and the corresponding generated activation code
nRetCode = SFLUC_INIT( szProdKey.c_str(), szLicenseKey.c_str(),szActivationCode.c_str(), &uLUCToken);
if(nRetCode == NDK_SUCCESS){
std::wcout << L" SUCCESS - License system is initialized" << std::endl;
// 3- Initialize the SDK system
unsigned int m_uSDKToken = unsigned(-1);
nRetCode = NDK_Init(szAppName.c_str(), NULL/*Temp Data Directory*/, 0L /*Timeout = default*/, &m_uSDKToken);
if(nRetCode == NDK_SUCCESS){
std::wcout << L" SUCCESS - Analytics SDK system is initialized" << std::endl;
// Verify the status
nRetCode = SFLUC_CHECK_LICENSE();
if( nRetCode == NDK_SUCCESS){
std::wcout << L" SUCCESS - License key is activated, and system is in pro mode" << std::endl;
// Now, Let call the simple brown exponential smoothing
double airline_data[156]={
112,118,132,129,121,135,148,148,136,119,104,118,
115,126,141,135,125,149,170,170,158,133,114,140,
145,150,178,163,172,178,199,199,184,162,146,166,
171,180,193,181,183,218,230,242,209,191,172,194,
196,196,236,235,229,243,264,272,237,211,180,201,
204,188,235,227,234,264,302,293,259,229,203,229,
242,233,267,269,270,315,364,347,312,274,237,278,
284,277,317,313,318,374,413,405,355,306,271,306,
315,301,356,348,355,422,465,467,404,347,305,336,
340,318,362,348,363,435,491,505,404,359,310,337,
360,342,406,396,420,472,548,559,463,407,362,405,
417,391,419,461,472,535,622,606,508,461,390,432,
444,416,472,499,497,579,667,657,557,492,425,481};
double alpha=0.3;
double retVal=0.0;
nRetCode = NDK_SESMTH(airline_data, 156, TRUE, &alpha, 1, TRUE, NULL, 0, &retVal);
if( nRetCode == NDK_SUCCESS){
// The SESMTH 1-step forecast is
std::wcout << L" SUCCESS - SESMTH returns: " << retVal << std::endl;
}
// Shutdown the SDK
NDK_Shutdown(TRUE, m_uSDKToken);
}
}
SFLUC_SHUTDOWN(uLUCToken);
}
std::cout << " Shutting down the Logging system ..." << std::endl;
SFLOG_SHUTDOWN(uLOGToken);
}
return 0;
}
int __stdcall NDK_Init(LPCWSTR szBaseName, LPCWSTR szDataPath, long consoleAppTimeout, unsigned int *pClientToken)
int __stdcall NDK_Shutdown(BOOL cleanup, unsigned int uClientToken)
int __stdcall NDK_SESMTH(double *pData, size_t nSize, BOOL bAscending, double *alpha, int nHorizon, BOOL bOptimize, double *internals, size_t nInternalsSize, double *retVal)
#define NDK_SUCCESS
int __stdcall SFLOG_INITW(LPCWSTR szAppName, LPCWSTR szLogDir, DWORD dwBackupFiles, size_t ulMaxFileSize, unsigned int *pClientToken)
int __stdcall SFLOG_SHUTDOWN(unsigned int uClientToken)
int __stdcall SFLUC_SHUTDOWN(unsigned int uLUCToken)
int __stdcall SFLUC_INIT(LPCWSTR argPRODKey, LPCWSTR argLicenseKey, LPCWSTR argActivationCode, unsigned *pClientToken)
int __stdcall SFLUC_CHECK_LICENSE(void)

See Also