Library functions πŸ”—

By library function (also LibraryLink function) we understand a C++ function with one of the following signatures

EXTERN_C DLLEXPORT int f (WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res);

or

EXTERN_C DLLEXPORT int f (WolframLibraryData libData, WSLINK wslp);

Such functions are building blocks of every LibraryLink paclet. They are usually called directly from the Wolfram Language after being loaded from the dynamic library first. It is common for paclets to also define functions entirely in the Wolfram Language or provide thin Wolfram Language wrappers around loaded library functions for instance in order to validate input data and then pass it down to the C++ code.

Function arguments πŸ”—

Passing data between Wolfram Language and external C or C++ libraries is a core feature of LibraryLink. This is far from a straightforward task, because in the Wolfram Language everything is an expression and variable’s type can change at run time, whereas C and C++ variables are statically typed. Apart from that, every C/C++ library may define custom data types it uses.

LibraryLink does the heavy lifting by providing translation between popular Wolfram Language expression types and corresponding C types. For instance, when you pass a String expression to the library function, you will receive a null-terminated char* in the C code, or passing a NumericArray will yield an object of type MNumericArray.

In practice, what you will receive in a library function as input arguments from the Wolfram Language is an array of MArgument, which is a union type:

typedef union {
        mbool *boolean;
        mint *integer;
        mreal *real;
        mcomplex *cmplex;
        MTensor *tensor;
        MSparseArray *sparse;
        MNumericArray *numeric;
        MImage *image;
        char **utf8string;
} MArgument;

Similarly, there is one MArgument to store the result of your library function that you want to return to the Wolfram Language. You must also remember that some types of arguments need special treatment, for example you must call UTF8String_disown on string arguments to avoid memory leaks.

Developers who are not familiar with this part of LibraryLink are encouraged to consult the official guide before reading on.

LLU hides all those implementation details in the MArgumentManager class. You still need to know what the actual argument types are but you can now extract arguments using member functions like getInteger, getString etc. and set the resulting value with set without worrying about memory management.

Example πŸ”—

Write a library function that adds two integers. First thing you need to do is to create an instance of MArgumentManager initialized with all arguments to the library function:

EXTERN_C DLLEXPORT int AddTwoIntegers(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
    LLU::MArgumentManager mngr {libData, Argc, Args, Res};
    auto n1 = mngr.get<mint>(0);  // get first (index = 0) argument, which is of type mint
    auto n2 = mngr.get<mint>(1);  // get second argument which is also an integer

    mngr.set(n1 + n2);  // set the sum of arguments to be the result
    return LLU::ErrorCode::NoError;
}

Such function, when compiled into a shared library, say myLib.so, could be loaded into WolframLanguage and used like this:

AddInts = LibraryFunctionLoad["myLib", "AddTwoIntegers", {Integer, Integer}, Integer];

AddInts[17, 25]
(* = 42 *)

Loading library functions πŸ”—

In the example above we saw how library functions can be loaded from shared objects via LibraryFunctionLoad:

FunctionNameInWL = LibraryFunctionLoad["path/to/sharedLibrary", "FunctionNameInCppCode", {ArgumentType1, ArgumentType2, ...}, ResultType];

The syntax is described in details in LibraryLink Β» Functions, Arguments, and Results.

In case of WSTP library functions, the call gets simplified to:

FunctionNameInWL = LibraryFunctionLoad["path/to/sharedLibrary", "FunctionNameInCppCode", LinkObject, LinkObject];

It is common but not in any way required to have FunctionNameInWL be equal to FunctionNameInCppCode with a $ prepended, e.g.

$FunctionName = LibraryFunctionLoad["path/to/sharedLibrary", "FunctionName", LinkObject, LinkObject]

LLU expands the library loading mechanism in LibraryLink by providing convenient wrappers with extra options:

SafeLibraryLoad[lib_]

Quietly attempts to load the dynamic library lib, and throws if it cannot be loaded.

PacletFunctionSet[resultSymbol_, lib_, f_, fParams_, fResultType_, opts___]

Attempts to load an exported function f from a dynamic library lib and assign the result to resultSymbol. By default, the dynamic library name is taken from the library given to InitializePacletLibrary (Paclet Library). A caveat is that if Paclet Library has been lazily initialized and PacletFunctionSet is called with a path to it, then auto-loading of Paclet Library will not be triggered. By default, the name of the library function is assumed to be the same as the symbol name (sans any leading or trailing $’s).

Arguments:
  • resultSymbol - a WL symbol to represent the loaded function

  • lib - name of the dynamic library [optional]

  • f - name of the function to load from the dynamic library [optional]

  • fParams - parameter types of the library function to be loaded

  • fResultType - result type

LazyPacletFunctionSet[resultSymbol_, lib_, f_, fParams_, fResultType_, opts___]

Lazy version of PacletFunctionSet which loads the function upon the first evaluation of resultSymbol.

WSTPFunctionSet[resultSymbol_, lib_, f_, opts___]

A convenient wrapper around PacletFunctionSet for easier loading of WSTP functions. Argument and result type are fixed as LinkObject.

LazyWSTPFunctionSet[resultSymbol_, lib_, f_, opts___]

Lazy version of WSTPFunctionSet which loads the function upon the first evaluation of resultSymbol.

MemberFunctionSet[exprHead_][memberSymbol_?Developer`SymbolQ, lib_, f_, fParams_, retType_, opts___]

Loads a library function into memberSymbol that can be invoked on instances of exprHead like so: instance @ memberSymbol[…]

LazyMemberFunctionSet[exprHead_][memberSymbol_?Developer`SymbolQ, lib_, f_, fParams_, retType_, opts___]

Lazy version of MemberFunctionSet which loads the function upon the first evaluation of memberSymbol.

WSTPMemberFunctionSet[exprHead_][memberSymbol_, lib_, f_, opts___]

A convenient wrapper around MemberFunctionSet for easier loading of WSTP member functions.

LazyWSTPMemberFunctionSet[exprHead_][memberSymbol_, lib_, f_, opts___]

Lazy version of WSTPMemberFunctionSet which loads the function upon the first evaluation of memberSymbol.

There is also one lower level function which does not take a symbol as first argument but instead returns the loaded library function as the result

PacletFunctionLoad[lib_, f_, fParams_, retType_, opts___]

Attempts to load an exported function f from a dynamic library lib and return it. Unlike PacletFunctionSet, there is no mechanism by which to avoid eager loading of the default paclet library (i.e. there is no LazyPacletFunctionLoad). If lib is omitted, the dynamic library name is taken from the library given to InitializePacletLibrary.

Supported options for all of the above functions include:

"Optional" -> True | False πŸ”—

Whether the library function is optional in the library, i.e. loading may fail quietly. Defaults to False.

"ProgressMonitor" -> None | _Symbol πŸ”—

Provide a symbol which will store the current progress of library function. See Progress monitor for details. Defaults to None.

"Throws" -> True | False πŸ”—

Whether the library function should throw Failure expressions on error or return them as the result. Defaults to True (so Failures will be thrown).

Reducing boilerplate code πŸ”—

The set of utility functions described in the previous section allows you to reduce the amount of code you need to write in order to load functions from your paclet’s dynamic library to the Wolfram Language. Similarly, LLU provides a number of macros that eliminate the need to repeat the full signature for every library function.

After you include <LLU/LibraryLinkFunctionMacro.h> instead of writing:

EXTERN_C DLLEXPORT int name (WolframLibraryData libData, mint Argc, MArgument* Args, MArgument Res);

you can type

This macro forward declares and begins the definition of an extern β€œC” LibraryLink function with given name.

For input parameter and return type explanation see the official LibraryLink guide. WolframLibraryData parameter is marked [[maybe_unused]] because it is a common workflow to take the instance of WolframLibraryData passed to WolframLibrary_initialize function and store it with LLU::LibraryData::setLibraryData so that it is accessible everywhere. With such setup one does not need to use the WolframLibraryData copy provided to every LibraryLink function.

And similarly instead of

EXTERN_C DLLEXPORT int name (WolframLibraryData libData, WSLINK wslp);

you can use

LIBRARY_WSTP_FUNCTION(name) πŸ”—

This macro forward declares and begins the definition of an extern β€œC” LibraryLink function with given name, which uses WSTP to exchange data with WolframLanguage.

For input parameter and return type explanation see the official LibraryLink guide. WolframLibraryData parameter is marked [[maybe_unused]] because it is a common workflow to take the instance of WolframLibraryData passed to WolframLibrary_initialize function and store it with LLU::LibraryData::setLibraryData so that it is accessible everywhere. With such setup one does not need to use the WolframLibraryData copy provided to every LibraryLink function.

Finally, if you use exception-based error handling you will often end up writing code like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
EXTERN_C DLLEXPORT int name(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
    auto err = ErrorCode::NoError;
    try {
        LLU::MArgumentManager mngr {libData, Argc, Args, Res};
        // body of a function that effectively takes mngr as the single parameter
    } catch (const LibraryLinkError& e) {
        err = e.which();
    } catch (...) {
        err = ErrorCode::FunctionError;
    }
    return err;
}

Fortunately, there is a macro that allows you to focus only on the highlighted part:

LLU_LIBRARY_FUNCTION(name) πŸ”—

This macro provides all the boilerplate code needed for a typical exception-safe LibraryLink function.

LLU_LIBRARY_FUNCTION(MyFunction) defines a LibraryLink function MyFunction and a regular function impl_MyFunction of type void(LLU::MArgumentManager&), which is the one you need to provide a body for. All LLU::LibraryLinkError exceptions thrown from impl_MyFunction will be caught and the error code returned to LibraryLink. All other exceptions will also be caught and translated to a FunctionError.

Note

While this macro saves quite a lot of typing it may also decrease code readability and make debugging harder so use with caution.

User-defined types πŸ”—

LibraryLink supports a number of types as function arguments and for the majority of use cases the built-in types are enough. However, imagine you are writing a library that operates on financial data and it processes amounts of money. For example, in the Wolfram Language you work with expressions like Quantity[20.3, "USD"] and in C++ you have a corresponding structure:

struct Money {
    double amount;
    std::string currency;
};

If you want to write a library function that takes an amount of money and a currency and converts that amount to the given currency, you will probably choose {Real, String, String} for argument types (Quantity would be split into Real and String and the second String is for the new currency) and "DataStore" for the return type. This requires some extra code on the Wolfram Language side to extract Real and String from the Quantity and on the C++ side to construct a DataStore from a Money object. Having large number of functions in the library that may repeat those translations, you will probably decide to factor this extra code to helper functions.

You could then use your library in Wolfram Language as follows:

(* Load raw library function that operates on basic LibraryLink types *)
$ConvertMoney = LibraryFunctionLoad["myLib.so", "ConvertMoney", {Real, String, String}, "DataStore"];

(* Create a higher-level wrapper for users of your package *)
ConvertMoney[amount_Quantity, newCurrency_String] := With[
   {
      rawlibraryResult = $ConvertMoney[QuantityMagnitude[amount], QuantityUnit[amount], newCurrency];
   },
   $dataStoreToQuantity[rawLibraryResult]  (* $dataStoreToQuantity is a small utility function, omitted for brevity *)
];

ConvertMoney[Quantity[50., "USD"], "PLN"]
(* = Quantity[XXX, "PLN"] *)

The implementation of ConvertMoney in C++ would go along the lines:

EXTERN_C DLLEXPORT int ConvertMoney(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
    LLU::MArgumentManager mngr {libData, Argc, Args, Res};
    auto amount = mngr.get<double>(0);
    auto oldCurrency = mngr.get<std::string>(1);
    auto newCurrency = mngr.get<std::string>(2);

    auto moneyToConvert = Money { amount, oldCurrency };
    Money converted = myLib::convert(moneyToConvert, newCurrency);

    mngr.set(myLib::MoneyToDataList(converted));  // myLib::MoneyToDataList is a helper function to convert Money object to a DataList
    return LLU::ErrorCode::NoError;
}

This is a fine code and if you are satisfied with it, you can stop reading here. However, it is possible with LLU to implement the same functionality like this:

(* Load "ConvertMoney" function from "myLib.so" and assign it to ConvertMoney symbol *)
`LLU`PacletFunctionSet[ConvertMoney, "myLib.so", "ConvertMoney", {"Money", String}, "Money"];

(* No need for separate higher-level wrapper because the types are translated by LLU now. *)

ConvertMoney[Quantity[50., "USD"], "PLN"]
(* = Quantity[XXX, "PLN"] *)

and in C++

EXTERN_C DLLEXPORT int ConvertMoney(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
    LLU::MArgumentManager mngr {libData, Argc, Args, Res};
    auto moneyToConvert = mngr.get<Money>(0);
    auto newCurrency = mngr.get<std::string>(2);  // under the hood Money object is still sent as two values (Real + String), so new currency has index 2

    Money converted = myLib::convert(moneyToConvert, newCurrency);

    mngr.set(converted);
    return LLU::ErrorCode::NoError;
}

The point is to delegate the translation between your types and LibraryLink types to LLU, so that you can write cleaner code that does not distract readers with technicalities. To achieve this, you need to teach LLU to understand your types. Here is how you register "Money" as a library function argument type, the values of which are of the form Quantity[_Real, _String]:

`LLU`MArgumentType["Money", {Real, String}, (Sequence[QuantityMagnitude[#], QuantityUnit[#]]) &];

The second argument is the list of basic LibraryLink types that constitute to a single expression of type "Money". The third argument is a translation function that takes something of the form Quantity[_Real, _String] and produces a Sequence of two values: Real and String.

In the C++ code we used mngr.get<Money>, which means we have to tell LLU how many and what basic LibraryLink types correspond to a Money object. This is achieved by defining a specialization of CustomType structure template and providing a type alias member CorrespondingTypes which must be a std::tuple of corresponding basic LibraryLink types:

template<>
struct LLU::MArgumentManager::CustomType<Money> {
   using CorrespondingTypes = std::tuple<double, std::string>;
};

With this information, whenever LLU is requested to read an argument of type Money it will read two consecutive input arguments as double and std::string, respectively, and construct a Money object from those 2 values.

In many cases this is sufficient, however in some situations you may want to have full control over how LLU creates objects of your type. Imagine we want to always capitalize the currency that is passed from Wolfram Language code, before creating a Money object. To have such fine-grained control over MArgumentManager’s behavior, we must additionally specialize a struct template Getter that provides a member function get, like this:

template<>
struct LLU::MArgumentManager::Getter<Money> {
   static Money get(const MArgumentManager& mngr, size_type index) {
      auto [amount, currency] = mngr.getTuple<double, std::string>(index);
      std::transform(currency.begin(), currency.end(), currency.begin(), [](unsigned char c){ return std::toupper(c); });
      return Money { amount, std::move(currency) };
   }
};

At this point, LLU knows how to change WL expressions of the form Quantity[_Real, _String] into Money objects in C++. The only thing left is to teach LLU how to work in the other direction, i.e. how to return Money objects via β€œDataStore” and change them into Quantity. First, let us specialize MArgumentManager::set template:

template<>
void LLU::MArgumentManager::set<Money>(const Money& m) const {
    DataList<NodeType::Any> moneyDS;
    moneyDS.push_back(m.amount);
    moneyDS.push_back(m.currency);
    set(moneyDS);
}

You can read more about DataList in the section about Containers. The last step is to tell LLU how to turn incoming DataStores into Quantities in library functions that declare β€œMoney” as return type:

`LLU`MResultType["Money", "DataStore", (Quantity @@ #)&];

Here we say that if a library function has return type β€œMoney”, then the corresponding LibraryLink type is β€œDataStore” and when we get such a DataStore we need to apply a function (Quantity @@ #)& to turn it into the form that we use to represent Money expressions.

Registering user-defined types in LLU may seem like a lot of extra work, but actually it is no extra work at all. It is merely a way to organize the code that you would previously have written anyway in the form of small utility functions scattered all over your library and possibly even duplicated, if you are not careful enough.

API reference πŸ”—

class LLU::MArgumentManager πŸ”—

Manages arguments exchanged between the paclet C++ code and LibraryLink interface.

MArgumentManager provides a safe way to access MArguments received from LibraryLink and takes care of memory management both for in- and out- arguments. Using MArgumentManager one can perform generic operations on NumericArrays, Tensors and Images independent of their data type.

Public Types

using size_type = std::size_t πŸ”—

Size type for indexing the list of arguments that MArgumentManager manages.

template<typename T>
using RequestedType = typename RequestedTypeImpl<T>::type πŸ”—

RequestedType<T> is usually just T and is used as return type of MArgumentManager::get(size_type)

Public Functions

MArgumentManager(mint Argc, MArgument *Args, MArgument &Res) πŸ”—

Constructor.

Parameters
  • [in] Argc: - number of MArguments provided

  • [in] Args: - MArguments provided

  • [in] Res: - reference to output MArgument

MArgumentManager(WolframLibraryData ld, mint Argc, MArgument *Args, MArgument &Res) πŸ”—

Constructor.

Parameters
  • [in] ld: - library data

  • [in] Argc: - number of MArguments provided

  • [in] Args: - MArguments provided

  • [in] Res: - reference to output MArgument

bool getBoolean(size_type index) const πŸ”—

Get MArgument of type mbool at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

MArgument of type bool at position index

double getReal(size_type index) const πŸ”—

Get MArgument of type mreal at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

MArgument of type double at position index

template<typename T>
T getInteger(size_type index) const πŸ”—

Get MArgument of type mint at position index with extra static_cast if needed.

Template Parameters
  • T: - integral type to convert mint to

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

MArgument value at position index converted to T

std::complex<double> getComplex(size_type index) const πŸ”—

Get MArgument of type mcomplex at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

MArgument value at position index converted to std::complex<double>

char *getCString(size_type index) const πŸ”—

Get value of MArgument of type β€œUTF8String” at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • LLErrorCode::MArgumentIndexError: - if index is out-of-bounds

Return

C-string which was received from LibraryLink

Note

MArgumentManager is responsible for disowning string arguments. Do not call free() or delete() on resulting pointer.

std::string getString(size_type index) const πŸ”—

Get value of MArgument of type β€œUTF8String” at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • LLErrorCode::MArgumentIndexError: - if index is out-of-bounds

Return

std::string which is created from MArgument at position index

template<typename T, Passing Mode = Passing::Automatic>
NumericArray<T> getNumericArray(size_type index) const πŸ”—

Get MArgument of type MNumericArray at position index and wrap it into NumericArray.

Template Parameters
Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

NumericArray wrapper of MArgument at position index

See

NumericArray<T>::NumericArray(const MNumericArray);

template<Passing Mode = Passing::Automatic>
GenericNumericArray getGenericNumericArray(size_type index) const πŸ”—

Get MArgument of type MNumericArray at position index and wrap it into generic MContainer wrapper.

Template Parameters
  • Mode: - passing mode to be used

Parameters
  • index: - position of desired MArgument in Args

Return

MContainer wrapper of MNumericArray with given passing mode

MNumericArray getMNumericArray(size_type index) const πŸ”—

Get MArgument of type MNumericArray at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Warning

Use of this function is discouraged. Use getNumericArray instead, if possible.

Return

MArgument at position index interpreted as MNumericArray

template<typename T, Passing Mode = Passing::Automatic>
Tensor<T> getTensor(size_type index) const πŸ”—

Get MArgument of type MTensor at position index and wrap it into Tensor object.

Template Parameters
  • T: - type of data stored in Tensor

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

Tensor wrapper of MArgument at position index

See

Tensor<T>::Tensor(const MTensor);

template<Passing Mode = Passing::Automatic>
GenericTensor getGenericTensor(size_type index) const πŸ”—

Get MArgument of type MTensor at position index and wrap it into generic MContainer wrapper.

Template Parameters
  • Mode: - passing mode to be used

Parameters
  • index: - position of desired MArgument in Args

Return

MContainer wrapper of MTensor with given passing mode

MTensor getMTensor(size_type index) const πŸ”—

Get MArgument of type MTensor at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Warning

Use of this function is discouraged. Use getTensor instead, if possible.

Return

MTensor of MArgument at position index

template<typename T, Passing Mode = Passing::Automatic>
SparseArray<T> getSparseArray(size_type index) const πŸ”—

Get MArgument of type MSparseArray at position index and wrap it into SparseArray.

Template Parameters
Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

SparseArray wrapper of MArgument at position index

template<Passing Mode = Passing::Automatic>
GenericSparseArray getGenericSparseArray(size_type index) const πŸ”—

Get MArgument of type MSparseArray at position index and wrap it into generic MContainer wrapper.

Template Parameters
  • Mode: - passing mode to be used

Parameters
  • index: - position of desired MArgument in Args

Return

MContainer wrapper of MSparseArray with given passing mode

MSparseArray getMSparseArray(size_type index) const πŸ”—

Get MArgument of type MSparseArray at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Warning

Use of this function is discouraged. Use getSparseArray instead, if possible.

Return

MArgument at position index interpreted as MSparseArray

template<typename T, Passing Mode = Passing::Automatic>
Image<T> getImage(size_type index) const πŸ”—

Get MArgument of type MImage at position index and wrap it into Image object.

Template Parameters
  • T: - type of data stored in Image

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

Image wrapper of MArgument at position index

See

Image<T>::Image(const MImage ra);

template<Passing Mode = Passing::Automatic>
GenericImage getGenericImage(size_type index) const πŸ”—

Get MArgument of type MImage at position index and wrap it into generic MContainer wrapper.

Template Parameters
  • Mode: - passing mode to be used

Parameters
  • index: - position of desired MArgument in Args

Return

MContainer wrapper of MImage with given passing mode

MImage getMImage(size_type index) const πŸ”—

Get MArgument of type MImage at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Warning

Use of this function is discouraged. Use getImage instead, if possible.

Return

MImage of MArgument at position index

template<typename T, Passing Mode = Passing::Automatic>
DataList<T> getDataList(size_type index) const πŸ”—

Get DataStore with all nodes of the same type from MArgument at position index.

Template Parameters
  • T: - type of data stored in each node of DataStore, it T is MArgumentType::MArgument it will accept any node

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

DataList wrapper of MArgument at position index

See

DataList<T>::DataList(DataStore ds);

template<Passing Mode = Passing::Automatic>
GenericDataList getGenericDataList(size_type index) const πŸ”—

Get MArgument of type DataStore at position index and wrap it into generic MContainer wrapper.

Template Parameters
  • Mode: - passing mode to be used

Parameters
  • index: - position of desired MArgument in Args

Return

MContainer wrapper of DataStore with given passing mode

DataStore getDataStore(size_type index) const πŸ”—

Get MArgument of type DataStore at position index.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Warning

Use of this function is discouraged. Use getDataList instead.

Return

DataStore of MArgument at position index

template<class ManagedExpr, class DynamicType = ManagedExpr>
DynamicType &getManagedExpression(size_type index, ManagedExpressionStore<ManagedExpr> &store) const πŸ”—

Get a reference to an instance of Managed Expression that was sent from Wolfram Language as argument to a library function.

Template Parameters
  • ManagedExpr: - registered Managed Expression class

  • DynamicType: - actual type of Managed Expression, this must be ManagedExpr or its subclass

Parameters
  • index: - position of desired argument in Args

  • store: - Managed Expression store that manages expressions of type ManagedExpr

Return

a reference to the Managed Expression

template<class ManagedExpr, class DynamicType = ManagedExpr>
std::shared_ptr<DynamicType> getManagedExpressionPtr(size_type index, ManagedExpressionStore<ManagedExpr> &store) const πŸ”—

Get a shared pointer to an instance of Managed Expression that was sent from Wolfram Language as argument to a library function.

Template Parameters
  • ManagedExpr: - registered Managed Expression class

  • DynamicType: - actual type of Managed Expression, this must be ManagedExpr or its subclass

Parameters
  • index: - position of desired argument in Args

  • store: - Managed Expression store that manages expressions of type ManagedExpr

Return

a shared pointer to the Managed Expression

template<typename T>
RequestedType<T> get(size_type index) const πŸ”—

Extract library function argument at given index and convert it from MArgument to a desired type.

Template Parameters
  • T: - any type, for types not supported by default developers may specialize this function template

Parameters
  • index: - position of desired argument in Args

Return

a value of type T created from the specified input argument

template<typename ...ArgTypes>
std::tuple<RequestedType<ArgTypes>...> getTuple(size_type index = 0) const πŸ”—

Extract arguments from the Manager and return them as values of given types.

Template Parameters
  • ArgTypes: - types that determine how each extracted argument will be returned

Return

a tuple of function arguments

template<typename ...ArgTypes>
std::tuple<RequestedType<ArgTypes>...> getTuple(std::array<size_type, sizeof...(ArgTypes)> indices) const πŸ”—

Extract arguments from the Manager at given positions and return them as values of given types.

Template Parameters
  • ArgTypes: - types that determine how each extracted argument will be returned

Parameters
  • indices: - position of desired arguments, need not be sorted, may contain repeated values

Return

a tuple of function arguments

void setBoolean(bool result) noexcept πŸ”—

Set result as output MArgument.

Parameters
  • [in] result: - boolean value to be returned to LibraryLink

void setReal(double result) noexcept πŸ”—

Set result as output MArgument.

Parameters
  • [in] result: - value of type double to be returned to LibraryLink

void setInteger(mint result) noexcept πŸ”—

Set result as output MArgument.

Parameters
  • [in] result: - value of type mint to be returned to LibraryLink

Warning

result will be implicitly casted to mint with no overflow check

template<typename T>
bool setMintAndCheck(T result) noexcept πŸ”—

Set result as output MArgument and check for overflow.

Template Parameters
  • T: - integral type to be casted to mint

Parameters
  • [in] result: - value to be returned to LibraryLink

Return

true iff overflow occurred and the value had to be clipped

void setComplex(std::complex<double> c) noexcept πŸ”—

Set c as output MArgument.

Parameters
  • [in] c: - value of type std::complex<double> to be returned to LibraryLink

void setString(const std::string &str) πŸ”—

Set str as output MArgument.

Parameters
  • [in] str: - reference to std::string to be returned to LibraryLink

void setString(const char *str) πŸ”—

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void setString(std::string &&str) πŸ”—

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<typename T>
void setNumericArray(const NumericArray<T> &na) πŸ”—

Set MNumericArray wrapped by na as output MArgument.

Template Parameters
Parameters
  • [in] na: - reference to NumericArray which should pass its internal MNumericArray to LibraryLink

void setMNumericArray(MNumericArray na) πŸ”—

Set MNumericArray as output MArgument.

Parameters
  • [in] na: - MNumericArray to be passed to LibraryLink

template<typename T>
void setTensor(const Tensor<T> &ten) πŸ”—

Set MTensor wrapped by ten as output MArgument.

Template Parameters
Parameters
  • [in] ten: - reference to Tensor which should pass its internal MTensor to LibraryLink

void setMTensor(MTensor t) πŸ”—

Set MTensor as output MArgument.

Parameters
  • [in] t: - MTensor to be passed to LibraryLink

template<typename T>
void setImage(const Image<T> &im) πŸ”—

Set MImage wrapped by im as output MArgument.

Template Parameters
Parameters
  • [in] im: - reference to Image which should pass its internal MImage to LibraryLink

void setMImage(MImage im) πŸ”—

Set MImage as output MArgument.

Parameters
  • [in] im: - MImage to be passed to LibraryLink

template<typename T>
void setDataList(const DataList<T> &ds) πŸ”—

Set DataStore wrapped in DataList ds as output MArgument.

Template Parameters
  • T: - type of data stored in each node of DataStore

Parameters
  • [in] ds: - const reference to DataList which should pass its internal DataStore to LibraryLink

void setDataStore(DataStore ds) πŸ”—

Set DataStore as output MArgument.

Parameters
  • [in] ds: - DataStore to be passed to LibraryLink

template<typename T>
void setSparseArray(const SparseArray<T> &sa) πŸ”—

Set MSparseArray wrapped by sa as output MArgument.

Template Parameters
Parameters
  • [in] sa: - reference to SparseArray which should pass its internal MSparseArray to LibraryLink

void setMSparseArray(MSparseArray sa) πŸ”—

Set MSparseArray as output MArgument.

Parameters
  • [in] sa: - MSparseArray to be passed to LibraryLink

void set(bool result) noexcept πŸ”—

Set result as output MArgument.

Parameters
  • [in] result: - boolean value to be returned to LibraryLink

void set(double result) noexcept πŸ”—

Set result as output MArgument.

Parameters
  • [in] result: - value of type double to be returned to LibraryLink

void set(mint result) noexcept πŸ”—

Set result as output MArgument.

Parameters
  • [in] result: - value of type mint to be returned to LibraryLink

Warning

result will be implicitly casted to mint with no overflow check

void set(std::complex<double> c) noexcept πŸ”—

Set c as output MArgument.

Parameters
  • [in] c: - value of type std::complex<double> to be returned to LibraryLink

void set(const std::string &str) πŸ”—

Set str as output MArgument.

Parameters
  • [in] str: - reference to std::string to be returned to LibraryLink

void set(const char *str) πŸ”—

Set str as output MArgument.

Parameters
  • [in] str: - reference to std::string to be returned to LibraryLink

void set(std::string &&str) πŸ”—

Set str as output MArgument.

Parameters
  • [in] str: - reference to std::string to be returned to LibraryLink

template<typename T>
void set(const NumericArray<T> &na) πŸ”—

Set MNumericArray wrapped by na as output MArgument.

Template Parameters
Parameters
  • [in] na: - reference to NumericArray which should pass its internal MNumericArray to LibraryLink

void set(const GenericNumericArray &na) πŸ”—

Set MNumericArray wrapped by na as output MArgument.

Parameters
  • [in] na: - reference to generic NumericArray which should pass its internal MNumericArray to LibraryLink

template<typename T>
void set(const SparseArray<T> &ten) πŸ”—

Set MSparseArray wrapped by sa as output MArgument.

Template Parameters
Parameters
  • [in] sa: - reference to SparseArray which should pass its internal MSparseArray to LibraryLink

void set(const GenericSparseArray &t) πŸ”—

Set MSparseArray wrapped by t as output MArgument.

Parameters
  • [in] t: - reference to generic SparseArray which should pass its internal MSparseArray to LibraryLink

template<typename T>
void set(const Tensor<T> &ten) πŸ”—

Set MTensor wrapped by ten as output MArgument.

Template Parameters
Parameters
  • [in] ten: - reference to Tensor which should pass its internal MTensor to LibraryLink

void set(const GenericTensor &t) πŸ”—

Set MTensor wrapped by t as output MArgument.

Parameters
  • [in] t: - reference to generic Tensor which should pass its internal MTensor to LibraryLink

template<typename T>
void set(const Image<T> &im) πŸ”—

Set MImage wrapped by im as output MArgument.

Template Parameters
Parameters
  • [in] im: - reference to Image which should pass its internal MImage to LibraryLink

void set(const GenericImage &im) πŸ”—

Set MImage wrapped by im as output MArgument.

Parameters
  • [in] im: - reference to generic Image which should pass its internal MImage to LibraryLink

template<typename T>
void set(const DataList<T> &ds) πŸ”—

Set DataStore wrapped in DataList ds as output MArgument.

Template Parameters
  • T: - type of data stored in each node of DataStore

Parameters
  • [in] ds: - const reference to DataList which should pass its internal DataStore to LibraryLink

void set(const GenericDataList &ds) πŸ”—

Set DataStore wrapped by ds as output MArgument.

Parameters
  • [in] ds: - reference to generic DataStore which should pass its internal DataStore to LibraryLink

template<typename T>
void set(const T &arg) πŸ”—

Set given value as a result of the library function.

Template Parameters
  • T: - any type, for types not supported by default developers are encouraged to specialize this function template

ProgressMonitor getProgressMonitor(double step = ProgressMonitor::getDefaultStep()) const πŸ”—

Get ProgressMonitor shared with WL Kernel.

Parameters
  • step: - step value for progress monitor

Return

A new instance of ProgressMonitor class.

Warning

If you haven’t specified β€œProgressMonitor” option when loading the library function with PacletFunctionSet, then the behavior of getProgressMonitor is undefined.

numericarray_data_t getNumericArrayType(size_type index) const πŸ”—

Get type of MNumericArray at position index in Args.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

MNumericArray type

template<Passing Mode, class Operator, class ...OpArgs>
void operateOnNumericArray(size_type index, OpArgs&&... opArgs) πŸ”—

Perform operation on NumericArray created from MNumericArray argument at position index in Args.

Template Parameters
  • Mode: - passing mode of the NumericArray that will be processed

  • Operator: - any callable class

  • OpArgs...: - types of arguments of operator() in class Operator

Parameters
  • [in] index: - position of MNumericArray in Args

  • [in] opArgs: - arguments of Operator::operator()

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Warning

Operator::operator() has to be a template that takes a const NumericArray<T>& as first argument

template<Passing Mode = Passing::Automatic, class Operator>
void operateOnNumericArray(size_type index, Operator &&op) πŸ”—

Perform operation on NumericArray created from MNumericArray argument at position index in Args.

Template Parameters
  • Mode: - passing mode of the NumericArray that will be processed

  • Operator: - any callable class

Parameters
  • [in] index: - position of MNumericArray in Args

  • [in] op: - callable object (possibly lambda) that takes only one argument - a NumericArray

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

unsigned char getTensorType(size_type index) const πŸ”—

Get type of MTensor at position index in Args.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

MTensor type

template<Passing Mode, class Operator, class ...Args>
void operateOnTensor(size_type index, Args&&... opArgs) πŸ”—

Perform operation on Tensor created from MTensor argument at position index in Args.

Template Parameters
  • Mode: - passing mode of the Tensor that will be processed

  • Operator: - any callable class

  • OpArgs...: - types of arguments of operator() in class Operator

Parameters
  • [in] index: - position of MTensor in Args

  • [in] opArgs: - arguments of Operator::operator()

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

  • ErrorName::MArgumentTensorError: - if MTensor argument has incorrect type

Warning

Operator::operator() has to be a template that takes a const Tensor<T>& as first argument

template<Passing Mode = Passing::Automatic, class Operator>
void operateOnTensor(size_type index, Operator &&op) πŸ”—

Perform operation on Tensor created from MTensor argument at position index in Args.

Template Parameters
  • Mode: - passing mode of the Tensor that will be processed

  • Operator: - any callable class

Parameters
  • [in] index: - position of MTensor in Args

  • [in] op: - callable object (possibly lambda) that takes only one argument - a Tensor

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

  • ErrorName::MArgumentTensorError: - if MTensor argument has incorrect type

imagedata_t getImageType(size_type index) const πŸ”—

Get type of MImage at position index in Args.

Parameters
  • [in] index: - position of desired MArgument in Args

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

Return

MImage type

template<Passing Mode, class Operator, class ...Args>
void operateOnImage(size_type index, Args&&... opArgs) πŸ”—

Perform operation on Image created from MImage argument at position index in Args.

Template Parameters
  • Mode: - passing mode of the Image that will be processed

  • Operator: - any callable class

  • OpArgs...: - types of arguments of operator() in class Operator

Parameters
  • [in] index: - position of MImage in Args

  • [in] opArgs: - arguments of Operator::operator()

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

  • ErrorName::MArgumentImageError: - if MImage argument has incorrect type

Warning

Operator::operator() has to be a template that takes a const Image<T>& as first argument

template<Passing Mode = Passing::Automatic, class Operator>
void operateOnImage(size_type index, Operator &&op) πŸ”—

Perform operation on Image created from MImage argument at position index in Args.

Template Parameters
  • Mode: - passing mode of the Image that will be processed

  • Operator: - any callable class

Parameters
  • [in] index: - position of MImage in Args

  • [in] op: - callable object (possibly lambda) that takes only one argument - an Image

Exceptions
  • ErrorName::MArgumentIndexError: - if index is out-of-bounds

  • ErrorName::MArgumentImageError: - if MImage argument has incorrect type

template<typename T>
struct CustomType πŸ”—

Helper structure that can be used to register user-defined argument types in LLU.

If you want a type X to be supported as template argument for MArgumentManager::get<>, you must specialize CustomType<> for X and this specialization must contain a type alias CorrespondingTypes which is defined to be a std::tuple of basic LibraryLink types, from which an object of type X can be constructed. See online docs and MArgumentManager unit tests for examples.

Template Parameters
  • T: - any type you would like to treat as a user-defined LibraryLink argument type

template<typename T>
struct Getter πŸ”—

Helper structure to fully customize the way MArgumentManager reads T as argument type.

If T is a user-defined argument type, LLU will by default attempt to create an object of type T by reading values of corresponding types and feeding it to a constructor of T. Specialize Getter<> to override this behavior.

Template Parameters
  • T: - any type, for which you would like full control over how MArgumentManager reads arguments of that type

Note

Every user-defined argument type must specialize CustomType<>, specializing Getter<> is optional.

Public Static Functions

T get(const MArgumentManager &mngr, size_type firstIndex) πŸ”—

A function that tells LLU how to interpret an object of a user-defined type as an argument of a library function This function is used internally by MArgumentManager::get.

Parameters
  • mngr: - an instance of MArgumentManager

  • firstIndex: - index of the first library function parameter to be used

Return

an object of type T constructed from library function arguments stored in mngr

template<class Container, Passing Mode>
struct Managed πŸ”—

Helper struct to β€œattach” a passing mode to container type when passing it as template argument to MArgumentManager::getTuple.

Template Parameters
  • Container: - any generic or strongly typed container wrapper type (e.g. GenericImage, Tensor<mint>, etc.)

  • Mode: - passing mode for the container

template<typename T>
struct Setter πŸ”—

Helper structure to fully customize the way MArgumentManager sets an object of type T as result of a library function.

Note

You can explicitly specialize MArgumentManager::set for your type T, but having Setter<> allows you to define partial specializations.

Public Static Functions

void set(MArgumentManager&, const T&) πŸ”—

A function that tells LLU how to send an object of a user-defined type as a result of a library function This function is used internally by MArgumentManager::set.