Support forum
wyDay blog
wyDay Home

Using TurboFloat with C, C++, & Objective-C

C/C++This article will give step-by-step instructions on how to add floating-licensing to your C, C++, or Objective-C app. There's also a full example app that you can download and play with without needing to add licensing to your app.

By the end of this article you'll have working floating-licensing integrated with your application, and thus the ability to sell individual copies of your software.

This article shows you how to add floating-licensing to your C or C++ app using TurboFloat. To add hardware-locked licensing to your app see the "Using TurboActivate with C, C++, and Objective-C " article.

Sign up or login and download the native TurboFloat library

Before you can do anything, you need to login to your LimeLM account (or sign up). Then download TurboFloat for Windows, macOS, Linux, or BSD. It contains the native library and source code examples needed to integrate floating-licensing in your C or C++ app:

Adding floating licensing to your appTurboActivate.dat and Version GUID

After you've created a new product, go to the version page of the product you will be adding licensing to. You will need to do 2 things:

  1. Download the TurboActivate.dat file for the product version.
  2. Make a note of the Version GUID.

You'll be including the TurboActivate.dat file in the same folder as the TurboFloat.dll file and you'll use the Version GUID in your code as part of integrating TurboFloat within your app.

Example project

Included in TurboFloat Library package is a simple example project. The TurboFloat.h header file contains all the functions you'll be using to add the floating licenses functionality to your app. Also, if you're targeting Windows, you need link against the "TurboFloat.lib" file.

#include "TurboFloat.h"
#ifdef _WIN32
    #pragma comment (lib, "TurboFloat.lib")

Step-by-step walkthrough

We're going to walk you through adding floating licensing to your app by using our C example application. If you haven't downloaded it already you can get the example app inside the TurboFloat Library package.

Step 1. Start the TurboFloat Server

Before you can continue, you need to start a TurboFloat Server instance. We recommend spinning-up a TurboFloat Server instance on our infrastructure using LicenseChest. Alternatively, your customers can host the TurboFloat Server on their own infrastructure by activating and installing the TurboFloat Server locally.

We recommend using our hosted TurboFloat Server option because it's fast, stable, up-to-date, and incredibly easy to deploy.

Step 2. Get the TurboFloat handle

In the example console C application you'll see the first things we do, besides including "TurboFloat.h", is creating a public variable that will contain the "handle" you'll be using in the TurboFloat functions:

#include "TurboFloat.h"

uint32_t tfHandle;

Then you get the "handle" by calling the TF_GetHandle() function:

int main(int argc, char* argv[])
    /* Get the handle that will be used for TurboFloat function

       TODO: paste your Version GUID here.
    tfHandle = TF_GetHandle(_T("PASTE-VERSION-GUID-HERE"));

Note: if your TurboActivate.dat file isn't in the same path as your executable, then you need to tell TurboFloat to load the TurboActivate.dat file before you can get the handle. You do that by calling the TF_PDetsFromPath() function before calling TF_GetHandle():

int main(int argc, char* argv[])
    /* Used to store TurboFloat responses. */
    HRESULT hr;

    hr = TF_PDetsFromPath(L"C:\\Path\\To\\TurboActivate.dat");

    if (hr != TF_OK)
        printf("Failed to load the TurboActivate.dat file. ");
        printf("TF_PDetsFromPath() returned %d. Look in TurboFloat.h for a human readable explanation of the error.\n", hr);
        return 1;

    tfHandle = TF_GetHandle(_T("PASTE-VERSION-GUID-HERE"));

Step 3. Set the lease callback function

The TurboFloat library handles all the details about renewing leases, retrying, etc. All you have to do is handle the cases where TurboFloat talks to your app and tells it something has changed (license lease failing to be renewed or new license field data). To do this you need to create a function to handle these callbacks from TurboFloat:

void TF_CC LeaseCallback(uint32_t status)
    switch (status)
        //TODO: reload any features using TF_GetFeatureValue().
        printf("TODO: reload any features using TF_GetFeatureValue()\n");


        printf("The lease has been dropped due to computer sleeping.\n");

        /* TODO: prompt the user to re-connected -- hide this prompt upon receipt of TF_CB_LEASE_REGAINED */

        printf("The lease has been successfully regained after a sleep.\n");

        /* TODO: hide a prompt to the user if shown during TF_CB_LEASE_DROPPED_SLEEP */

    // explicitly handle errors
    // also, handle unknown statuses ("default")
    // as errors.
    case TF_CB_EXPIRED:

        //TODO: disable any features in your app.
        printf("The lease expired or has been dropped.\n");

        After disabling the user's access to your app, we recommend
        you do 3 things:

        1. Give the user the option to save their progress.

        2. Give the user the option to save their progress to a
           separate file (i.e. "Save as" in case the work they were
           doing was incomplete).

        3. Give the user the option to retry. For example a
           "Try again" button that calls TF_RequestLease(tfHandle).


        // Don't just exit the app without warning or without
        // giving the user options. For example, this behavior
        // right here is a terrible example to be setting:
        printf("The app is exiting. In your app you shouldn't just abruptly exit! That's bad. See the comments in the example app.\n");

Also, make note of the TF_CC before the function name:

void TF_CC LeaseCallback(uint32_t status){ ...

This tells your compiler to use the "cdecl" calling convention on Windows. This is required by TurboFloat. On other platforms (Linux, Mac OS X, etc.) it doesn't do anything — you can just leave the TF_CC declaration in there an the compiler will ignore it.

Next, we need to tell TurboFloat about the callback function:

tfHandle = TF_GetHandle(_T("PASTE-VERSION-GUID-HERE"));

   Set the function that TurboFloat will call from
   another thread letting your app know about changes
   to the floating license.
hr = TF_SetLeaseCallback(tfHandle, LeaseCallback);

Step 4. Requesting the lease from the TurboFloat Server

Now it's simply a matter of requesting the lease from the TurboFloat Server using the TF_RequestLease() function:

tfHandle = TF_GetHandle(_T("PASTE-VERSION-GUID-HERE"));
hr = TF_SetLeaseCallback(tfHandle, LeaseCallback);

hr = TF_RequestLease(tfHandle);

if (hr == TF_E_SERVER)
     We're just hardcoding the localhost for testing
     purposes in real life you'd want to let the user
     enter the host address / port you can either do
     this in your app, or in your installer.

     If your customer is using LicenseChest hosted TFS
     instances, you might want to make a simple prompt
     for the LicenseChest TFS UUID.

     More information:

     Then call TF_SaveServer(...) using
     "[UUID]" as the host address.

     For example:

     hr = TF_SaveServer(tfHandle, _T(""), 443, TF_USER | TF_REQUEST_OVER_HTTPS);
    hr = TF_SaveServer(tfHandle, _T(""), 13, TF_SYSTEM);

    if (hr != TF_OK)
        printf("Failed to save the sever details (TF_SaveServer() returned %d). Look in TurboFloat.h for a human readable explanation of the error.\n", hr);
        return 1;

    /* try to get a lease again */
    hr = TF_RequestLease(tfHandle);
else if (hr == TF_E_INET
      || hr == TF_E_INET_TIMEOUT
      Give the user an option to try another server if they
      couldn't connect to the first one, or if the first one
      is for a different product.

// If the lease wasn't acquired then output an error and exit.
// You can view all the error codes in TurboFloat.h near the bottom of the file.
if (hr != TF_OK)
    printf("Failed to get the floating license lease (TF_RequestLease() returned %d). Look in TurboFloat.h for a human readable explanation of the error.\n", hr);
    return 1;

Also notice how we're handling the case where the end-user hasn't already specified the floating license server (the TF_E_SERVER error). Instead of just hardcoding the server and port (like we show in the example), you should prompt the user to enter the details. Then you can call the TF_SaveServer() function to save the details.

You should also give your customers the ability to easily choose using TFS instances hosted on our infrastructure using LicenseChest by simply prompting them to enter the server UUID (a small string that uniquely identifies their TFS instance). Then it's simply a matter of calling TF_SaveServer() and appending the user-entered UUID to the hosted TFS address like so:

hr = TF_SaveServer(tfHandle, _T(""), 443, TF_USER | TF_REQUEST_OVER_HTTPS);

Step 5. Dropping the lease when your app closes

After you've successfully requested a lease from the TurboFloat Server, the TurboFloat library integrated in your app takes care of renewing the leases automatically and silently. You'll only ever get a notification of something going wrong in the callback function that we covered in Step 3.

When your app is closing you should "drop" the lease using the TF_DropLease() function, and cleanup the memory using the TF_Cleanup() function::

/* Drop the floating license, wait for the response,
   then exit your app.
if (TF_HasLease(tfHandle) == TF_OK)
    hr = TF_DropLease(tfHandle);

/* Output the error if there is one.
   Look in TurboFloat.h for what the error codes mean.
if (hr != TF_OK)
    printf("Dropping the lease failed: (%d), exiting anyway.\n", hr);

/* Cleanup the memory. */
hr = TF_Cleanup();

What this does is tell the TurboFloat Server that you're through using the lease in this instance of your app, and another instance of your app on another computer or another session can now use that "free slot".

If you can't drop the lease (because your app can't connect to the internet, or for any other reason), and you choose to exit your app anyway, then the "lease" on the TurboFloat Server will be a "zombie". The lease will expire eventually on the TurboFloat Server, and thus the free slot will open back up.

Step 6: Testing the lease callback function

Testing requesting leases, dropping them, and everything else in the TurboFloat Library is intuitive: just call the function and it does the thing you want it to do. Testing the lease callback function is, however, slightly less intuitive. Here's how you can test the callback function:

  1. If your app is open and has a lease, close your app and make sure it drops the license lease from the TurboFloat Server.

  2. Stop the TurboFloat Server instance.

  3. Open the TurboFloat Server config file, and edit <lease .../> element and set it to "30". This will set the lease length to 30 seconds.

  4. Save the changes you made to the configuration file.

  5. Start your TurboFloat Server instance again.

  6. Start your app again, and make sure it successfully gets a license lease from the TurboFloat Server.

  7. Now, stop the TurboFloat Server instance, but leave your app running.

  8. Within the next 30 seconds the lease callback function will be called because the TurboFloat Library was not able to renew the license lease automatically.

You should also test the "TF_CB_LEASE_DROPPED_SLEEP" and "TF_CB_LEASE_REGAINED" callback types. These callbacks are raised when your app has a lease and the device your app is running on goes to sleep and then eventually wakes up. To test these scenarios:

  1. Run a TurboFloat Server on a separate computer than the one you're running the test from (or spin up a TurboFloat Server instance on our infrastructure).

  2. Start your app and acquire a lease from that TFS instance.

  3. Put the computer which your app is running on to sleep.

  4. After the computer has gone to sleep, wake it up.

  5. Your app should handle both of those events seamlessly. Namely, prompting the user to reconnect when the computer goes to sleep, and if the lease is regained automatically, hiding that prompt from the user.