Getting Started

Compatible with Office 365.


github.com/bijoux_plugin/xll/blob/master/ExcelSDK/ 

Visual Studio 2022

Download the SDK to the following folder: C:\XLL\

C:\XLL\Excel2013XLLSDK\ 

Create a new project
language - C++, platform - Windows, project - Library
Dynamic Link Library (DLL)
Enter a project name and place the solution and project in the same folder


Precompiled Headers

Switch off precompiled headers.
Change this project property to switch off precompiled headers.

Project Properties > Configuration Properties > C/C++ > Precompiled Headers 
Precompiled Header - Not Using Precompiled Headers

Change this project property to remove the precompiled header file.
Remove the "pch.h" header file.

Project Properties > Configuration Properties > C/C++ > Precompiled Headers 
Precompiled Header File - (blank)

xlcall.h

This file is part of the Excel 2013 SDK.
This is a header file that contains all the necessary data structures, constant definitions and enumerations that are used by Excel.
It also contains all the C API interface functions that are needed for information to pass between Excel and the DLL.
We don't need to add this file to the actual project we just need to be able to link to this file.
This file is linked at compile time and the code is embedded into your solution.
Change this project property and add this folder.

Project Properties > Configuration Properties > C/C++ > General 
Additional Include Directories - C:\XLL\Excel2013XLLSDK\Include\

(do not use VC++ Directories > Include Directories)


xlcall32.lib

This file is part of the Excel 2013 SDK.
This is a static import library that contains all the symbol definitions and function declarations that are implemented in the xlcall32.dll
We don't need to add this file to the actual project we just need to be able to link to this file.
This file is linked at compile time and the code is embedded into your solution.
Change this project property and add this folder.

Project Properties > Configuration Properties > Linker > General 
Additional Library Directories - C:\XLL\Excel2013XLLSDK\LIB\x64\

(do not use VC++ Directories > Library Directories)


xlcall.cpp

This file is part of the Excel 2013 SDK.
This is a source file that contains the code for the Excel12() and Excel12v() functions.
This file is necessary because these two functions are not exported by the xlcall32.lib or xlcall32.dll files.
This file needs to be added to your project and is therefore dynamically linked to the Excel callback.
Copy the following file.

C:\XLL\Excel2013XLLSDK\SRC\xlcall.cpp 

Paste this file into the project folder and add this file to the project (Project > Add Existing Item).

C:\Users\"username"\source\repos\"myprojectname"\xlcall.cpp 

example.c

This file is part of the Excel 2013 SDK.
This source file contains everything you need to register and unregister user defined functions.
Copy the following file.

C:\XLL\Excel2013XLLSDK\Samples\example\example.c 

Paste this file into the project folder and add this file to the project (Project > Add Existing Item).

C:\Users\"username"\source\repos\"myprojectname"\example.c 

Change the angle brackets and replace them with quotes.
This is to tell the compiler to look in the source file directory for this file first, before looking in the include paths.
We will add the FRAMEWRK.h file to our project eventually.

#include <FRAMEWRK.h> 
#include "FRAMEWRK.h"

example.c - xlAutoOpen

The original file registers a large number of functions but for this example we are only going to register one of them.
Replace the following function so it only registers the function called "CalcCircum".

__declspec(dllexport) int WINAPI xlAutoOpen(void) 
{
  static XLOPER12 xDLL;

/* Get the XLL filename */
  Excel12f(xlGetName, &xDLL, 0);

  Excel12f(xlfRegister, 0, 4,
          (LPXLOPER12)&xDLL,
          (LPXLOPER12)TempStr12(L"CalcCircum"),
          (LPXLOPER12)TempStr12(L"BB"),
          (LPXLOPER12)TempStr12(L"CalcCircum"));

/* Free the XLL filename */
   Excel12f(xlFree, 0, 1, (LPXLOPER12)&xDLL);

/* Display a dialog box indicating that the XLL was successfully added */
   XCHAR szBuf[255];
   wsprintfW((LPWSTR)szBuf, L"xlAutoOpen has run successfully");
   Excel12f(xlcAlert, 0, 2, TempStr12(szBuf), TempInt12(2));

   return 1;
}

example.c - xlAutoClose

Replace the following function so it unregisters the function called "CalcCircum".

Excel12f(xlfSetName, 0, 1, TempStr12(L"CalcCircum")); 

example.c - CalcCircum

This file includes the definition of the CalcCircum function at the bottom of the example.c file.

__declspec(dllexport) double WINAPI CalcCircum(double pdRadius) 
{
   return pdRadius * 6.283185308;
}

example.c

On line 808 change the "(HANDLE)" to "(HANDLE)(INT_PTR)"

??? 

example.def

In this example we are exporting our functions so we do not need to include this file as well.
If your functions are not being exported they can be supplied in a ".def" file.
If you are using a ".def" file you need to add the name of the file here.

Project Properties > Configuration Properties > Linker > Input 
Module Definition File = example.def

framewrk.c

Copy the following file and paste them into the project folder.

C:\XLL\Excel2013XLLSDK\SAMPLES\FRAMEWRK\FRAMEWRK.c 

Add the following existing item to the project.

C:\Users\"username"\source\repos\"myprojectname"\ 

Comment out this header from the top of the file.

'#include <xlcall.cpp>

Change the angle brackets and replace them with quotes.

#include <FRAMEWRK.h> 
#include "FRAMEWRK.h"

Change the angle brackets and replace them with quotes.

#include <memorymanager.h> 
#include "memorymanager.h"

On line 252 change the "Excel4v" reference to "Excel12v".

xlret = Excel12v(xlfn,pxResult,count,(LPXLOPER *)ppxArgs); 

On line 991 change the "Excel4v" reference to "Excel12v".

wRet = Excel12v(xlSheetId, lpx, 0); 

On line 223 comment out function "Excel" because we do not need backwards compatibility.
On line 975 comment out function "TempActiveRef".
On line 1101 comment out function "TempActiveCell"
On line 1157 comment out function "TempActiveRow"
On line 1215 comment out function "TempActiveColumn"


framewrk.h

On line ?? comment out these lines

??? 


Add Files

C:\XLL\Excel2013XLLSDK\SAMPLES\FRAMEWRK\FRAMEWRK.h 
C:\XLL\Excel2013XLLSDK\SAMPLES\FRAMEWRK\MemoryManager.h
C:\XLL\Excel2013XLLSDK\SAMPLES\FRAMEWRK\MemoryManager.cpp
C:\XLL\Excel2013XLLSDK\SAMPLES\FRAMEWRK\MemoryPool.h
C:\XLL\Excel2013XLLSDK\SAMPLES\FRAMEWRK\MemoryPool.cpp

Add the following existing items to the project.

C:\Users\"username"\source\repos\"myprojectname"\ 

Remove Files

Remove the following files from the project.

framework.h 
pch.h
dllmain.cpp
pch.cpp

Target File Extension

Change the target file extension from ".dll" to ".xll".

Project Properties > Configuration Properties > Advanced 
Target File Extension = .xll

Build Solution

Check the selected platform.

Build > Configuration Manager 

Active solution platform = x64

Build > Build Solution 

Testing the Function in Excel

To test the function we need to load the add-in into Excel.
There are two ways you can do this: either through Visual Studio or manually browsing to the file.
It is possible to launch Excel from within Visual Studio.

Project Properties > Configuration Properties > Debugging 
Command = C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE

This will add the necessary registry key automatically and will start Excel with a new blank workbook.

Debug > Start Debugging 

Alternatively you can open Excel and browse to the add-in to install it.
Developer Tab, Excel Add-ins, Browse.

C:\XLL\Debug\XLL.xll 

Testing the Function

In Excel type ="CalcCircum(12)" into a cell.


ReturnString

This function returns a text string.
This function take 2 parameters, both numbers.

Excel12f(xlfRegister, 0, 4, 
   (LPXLOPER12)&xDLL,
   (LPXLOPER12)TempStr12(L"XL_ReturnString"),
   (LPXLOPER12)TempStr12(L"UBB"),
   (LPXLOPER12)TempStr12(L"XL_ReturnString"));

__declspec(dllexport) LPXLOPER12 WINAPI XL_ReturnString(double P, double T)
{
   static XLOPER12 xResult;
   xResult.xltype = xltypeStr;
   xResult.val.str = L"\023BetterSolutions.com";
   return(LPXLOPER12)&xResult;
}

ReturnArray

This function returns a (1 x 2) array containing two values.
This function has no parameters.

Excel12f(xlfRegister, 0, 4, 
  (LPXLOPER12)&xDLL,
  (LPXLOPER12)TempStr12(L"XL_ReturnArray"),
  (LPXLOPER12)TempStr12(L"Q"),
  (LPXLOPER12)TempStr12(L"XL_ReturnArray"));

__declspec(dllexport) LPXLOPER12 WINAPI XL_ReturnArray(void)
{
   static XLOPER12 xlArray; // not thread safe because it is static
   XLOPER12 xlValues[2];

   xlValues[0].xltype = xltypeNum;
   xlValues[1].xltype = xltypeNum;
   xlValues[0].val.num = 123;
   xlValues[1].val.num = 456;

   xlArray.xltype = xltypeMulti;
   xlArray.val.array.rows = 1;
   xlArray.val.array.columns = 2;
   xlArray.val.array.lparray = &xlValues;

   return (LPXLOPER12)&xlArray;
}

ReturnArrayDimensions

This function returns an array with a given size containing random numbers.
This function takes 2 parameters, to specify the number of rows and columns.

Excel12f(xlfRegister, 0, 4, 
   (LPXLOPER12)&xDLL,
   (LPXLOPER12)TempStr12(L"XL_ReturnArrayDimensions"),
   (LPXLOPER12)TempStr12(L"QJJ"),
   (LPXLOPER12)TempStr12(L"XL_ReturnArrayDimensions"));

__declspec(dllexport) LPXLOPER12 WINAPI XL_ReturnArrayDimensions(int columns, int rows)
{
  static XLOPER12 xlArray;

  int totalcells;
  totalcells = columns * rows;

  LPXLOPER12 xlValues3 = (LPXLOPER12)malloc(totalcells * sizeof(XLOPER12));

  if (xlValues3 != NULL){

  for (int c = 0; c < totalcells; c++)
  {
     xlValues3[c].xltype = xltypeNum;
     xlValues3[c].val.num = rand(); // built-in C function
  }

  // Free the memory
  //free(xlValues3);
  //xlValues2 = NULL; // optional but recommended to avoid dangling pointer

  xlArray.xltype = xltypeMulti;
  xlArray.val.array.columns = columns;
  xlArray.val.array.rows = rows;
  xlArray.val.array.lparray = xlValues3;
}

return (LPXLOPER12)&xlArray;


From the Book

Page 124
The xlAutoFree12 function is an XLL interface function that will be automatically called to release memory.
This function will be called automatically when functions return pointers back to Excel.
Assume all string elements were allocated using malloc, and need to be freed using free. Then free the array itself.

__declspec(dllexport) void WINAPI xlAutoFree12(LPXLOPER12 pxFree) 
{
    if(pxFree->xltype & xltypeMulti)
    {
        int size = pxFree->val.array.rows * pxFree->val.array.columns;
            
        LPXLOPER12 p = pxFree->val.array.lparray;

        for(; size-- > 0; p++) // check elements for strings
        {
            if((p->xltype & ~(xlbitDLLFree | xlbitXLFree)) == xltypeStr)
            {
                if(p->xltype & xlbitDLLFree)
                {
                   free(p->val.str);
                }
                else if(p->xltype & xlbitXLFree)
                {
                   Excel12(xlFree, 0, 1, p);
                }
            }
        }
        free(pxFree->val.array.lparray);
    }
    else if(pxFree->xltype == (xltypeStr | xlbitDLLFree))
    {
        free(pxFree->val.str);
    }
    else if(pxFree->xltype == (xltypeRef | xlbitDLLFree))
    {
        free(pxFree->val.mref.lpmref);
    }
// Assume pxFree was itself dynamically allocated using malloc.
    free(pxFree);
}

© 2026 Better Solutions Limited. All Rights Reserved. © 2026 Better Solutions Limited TopPrevNext