Building Quantlab DLLs in C++

The C++ Project

The standard function library of Quantlab may be enriched by objects and functions written by the user in a C++ environment. The objects and functions are written in a DLL that communicates with Quantlab through the Quantlab API.

When Quantlab is started, it loads all DLL-files located in the configured library directory. These DLL-files may add objects and functions into QLang (the Quantlab language), which then can be used from within Quantlab just like any of the original Quantlab objects and functions.

Required Files

Start by creating a C++ project that produces a DLL as output (In Microsoft Visual C++: File – New – Project – Win32 Dynamic-Link Library). The project name is not important as long as the name of the output DLL is unique.

Add qlab31-64.lib to enable linking your code to Quantlab types and functions. Include ql.h (located in Quantlab/api/include) in every source file. This is a master include that pulls in the entire public API:

Header

Contents

ql.h

Master include – just includes the other 3

ql_object.h

Primitive types (int_t, number_t, date_t, etc.), object, handle, handle_t<T>, num_val_t, error_t enum

ql_base.h

Runtime functions: validation, null sentinels, string/vector/matrix/series create/get/set, error(), date/calendar, blob

ql_init.h

Registration: add_module, add_object_type, add_func, add_mem_func, add_constructor, add_enum_type, seal_object_type, plus helpers R(), A(), A_0(), A_out(), A_ctxt()

Note: only these 3 header files exist in the public API. There are no separate ql_string.h, ql_calendar.h, etc.

#include <QL/api/ql.h>

Build Settings

CRITICAL: Quantlab uses static CRT (/MT). Your QLL MUST match. Using dynamic CRT (/MD) creates two separate heaps – objects allocated by Quantlab and freed by the QLL (or vice versa) cause silent crashes in release mode and immediate crashes in debug mode.

Setting

Required Value

Consequence if Wrong

Runtime Library (Release)

/MT (MultiThreaded)

Heap mismatch -> silent crash

Runtime Library (Debug)

/MTd (MultiThreadedDebug)

Heap mismatch -> immediate crash

Character Set

MultiByte

String corruption

SubSystem

Windows

Load failure

Platform

x64

Won’t load

Exception Handling

/EHsc (Sync)

Exception propagation failure

Runtime Type Info

/GR- (disabled)

Binary size, compatibility

Language Standard

C++17

Missing features

Platform Toolset

v143 (VS2022)

ABI mismatch

Verification: Run dumpbin /dependents your-module-64.qll. A correct QLL shows only qlab31-64.dll, KERNEL32.dll, and any backend DLLs you use. If you see MSVCP140.dll, VCRUNTIME140.dll, or api-ms-win-crt-*.dll, the CRT is wrong – rebuild with /MT.

Use a native Visual Studio .vcxproj for QLL builds.

Delay-Loading Third-Party DLLs

If your QLL links against external DLLs (e.g., xgboost.dll, onnxruntime.dll), use the /DELAYLOAD linker option so they load on first use, not at QLL init time. Without delay-loading, Quantlab debug mode crashes when loading the QLL.

<!-- In .vcxproj linker settings -->
<AdditionalDependencies>qlab31-64.lib;xgboost.lib;delayimp.lib</AdditionalDependencies>
<DelayLoadDLLs>xgboost.dll</DelayLoadDLLs>

Output Configuration

Configure your project to output a .qll file (a DLL with custom extension):

<TargetName>module_name-64</TargetName>
<TargetExt>.qll</TargetExt>

Deploy the compiled QLL to the folder specified in Quantlab’s Tools -> Options (DLLs used by Quantlab). Restart Quantlab after deployment.