Skip to content

Adding functions to the dynamic link library

Implement the functionality in the ExtendedLibraryFunctions.cpp source file. The code should resemble the following:

// ExtendedLibraryFunctions.cpp : Defines the initialization routines for the DLL.
//
#include "stdafx.h"
#include "ExtendedLibraryFunctions.h"
#include <string>

std::string SmallNumberToWords(int iNumberToConvert, std::string sWords)
{
    if (iNumberToConvert <= 0)
    {
        return sWords;
    }

    if (sWords.length() > 0)
    {
        sWords += " ";
    }

    std::string UnitsMap[] = { "zero","one","two","three","four","five","six","seven","eight","nine","ten",
        "eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen" };
    std::string TensMap[] = { "zero","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety" };

    if (iNumberToConvert < 20)
    {
        sWords += UnitsMap[iNumberToConvert];
    }
    else
    {
        sWords += TensMap[iNumberToConvert / 10];
        if ((iNumberToConvert % 10) > 0)
        {
            sWords += "-" + UnitsMap[iNumberToConvert % 10];
        }
    }
    return sWords;
}

std::string IntegerToWords(int iNumberToConvert)
{
    std::string sWords = "";

    if (iNumberToConvert == 0)
    {
        return "zero";
    }
    else
    {
        if (iNumberToConvert < 0)
        {
            return "minus " + IntegerToWords(abs(iNumberToConvert));
        }
        else
        {
            if (iNumberToConvert / 1000000000 > 0)
            {
                sWords += IntegerToWords(iNumberToConvert / 1000000000) + " billion ";
                iNumberToConvert %= 1000000000;
            }

            if (iNumberToConvert / 1000000 > 0)
            {
                sWords += IntegerToWords(iNumberToConvert / 1000000) + " million ";
                iNumberToConvert %= 1000000;
            }

            if (iNumberToConvert / 1000 > 0)
            {
                sWords += IntegerToWords(iNumberToConvert / 1000) + " thousand ";
                iNumberToConvert %= 1000;
            }

            if (iNumberToConvert / 100 > 0)
            {
                sWords += IntegerToWords(iNumberToConvert / 100) + " hundred";
                iNumberToConvert %= 100;
            }

            sWords = SmallNumberToWords(iNumberToConvert, sWords);
            return sWords;
        }
    }
}

std::string NumberToWords(double nNumberToConvert, int iNumberOfDecimals)
{
    int FirstPart = (int)nNumberToConvert;
    int SecondPart = std::round((nNumberToConvert - FirstPart) * pow(10, iNumberOfDecimals));
    if (SecondPart < 0)
        SecondPart = SecondPart * -1;
    std::string sWordsPart1 = IntegerToWords(FirstPart);
    std::string sWordsPart2 = SmallNumberToWords(SecondPart, "");
    if ((iNumberOfDecimals > 0) && sWordsPart2.length() > 0)
    {
        return sWordsPart1 + " and " + sWordsPart2;
    }
    else
    {
        return sWordsPart1;
    }
}

// this function will be exposed
// ELF functions must use parameters to be passed as type VARIANT
VARIANT __declspec(dllexport) number2words(VARIANT vNumberToConvert, VARIANT vDecimalPositions)
{
    CComVariant vRes, vNum, vPos;
    std::string sWords;

    USES_CONVERSION;

    vNum = vNumberToConvert;
    vPos = vDecimalPositions;

    // Convert data to bigint
    vNum.ChangeType(VT_R8, NULL);
    // Convert data to integer
    vPos.ChangeType(VT_I4, NULL);

    // Check argument types
    if (vNum.vt != VT_R8) // VT_R8 = double
    {
        vRes.vt = VT_ERROR;
        vRes.scode = MAKE_HRESULT(1, FACILITY_ITF, IDS_PARAM1_NO_DOUBLE);
        return vRes;
    }
    if (vPos.vt != VT_I4) // VT_I4 = 4 byte signed int
    {
        vRes.vt = VT_ERROR;
        vRes.scode = MAKE_HRESULT(1, FACILITY_ITF, IDS_PARAM2_NO_INTEGER);
        return vRes;
    }

    sWords = NumberToWords(vNum.dblVal, vPos.intVal);
    // Return the words
    vRes = sWords.c_str();
    return vRes;
}

Open the ExtendedLibraryFunctions.def file to define the function to be exported. Make the content as in the following picture.

Export Functions

Open the ExtendedLibraryFunctions.rc file to define version numbers, copyright, and add two error texts to the string table so that DataFlex Reports can produce an error about the problems found.

Adding Functions to the DLL

If the above (string table) is skipped, replace the IDS_PARAM1_NO_DOUBLE and IDS_PARAM2_NO_INTEGER used in the source code with some integer value. The DLL will not be created if the constants are not there.

Now the library is finished and can be built. To build the library, click on the menu Build and select Build Solution.