HOW TO: How do I use a vector<int> as an argument or a result?
Reference: Q0022
Article last modified on 28-Mar-2006
The information in this article applies to:
- XLL+ for Visual Studio 2005 - 5.0
- XLL+ for Visual Studio .NET - 4.2, 4.3.1, 5.0
- XLL+ for Visual Studio 6 - 3, 4.1, 4.2, 4.3.1, 5.0
How do I use a vector<int> as an argument or a result?
Question
The XLL+ Function Wizard lets me specify integer vector arguments, but only of
the following types: long
, short
and unsigned short
.
How do I specify a vector of type vector<int>
?
Answer
The XLL+ Function Wizard does not directly support the int
integer
type. (For the reasons, see "Background" below.)
vector<int> input arguments
If your code requires a vector <int> as an input, you need to write the code (3 lines of it) yourself, instead of letting the Function Wizard write it for you.
-
In the Function Wizard, set the type to be
COper
. - In your add-in function declare a local variable of type vector<int> to accept the input values.
-
Call the
COper::ReadVector(...)
method to read and validate the input. -
If
ReadVector
fails (i.e. returns FALSE), return the error information which is placed intoxloResult
byReadVector
.
The example function below demonstrates this technique.
Returning a vector<int>
To return a vector<int> value, you cannot use the standard operator=
overload, since this will cast all items in the vector to boolean values.
Instead, use the CXlOper::FromNumericVector(...)
method to copy
the vector's values to the CXlOper containing the function's result.
Example
// Function: IntArray // Purpose: Takes an array of integers as an argument //{{XLP_SRC(IntArray) // NOTE - the FunctionWizard will add and remove mapping code here. // DO NOT EDIT what you see in these blocks of generated code! IMPLEMENT_XLLFN2(IntArray, "RP", "IntArray", "A", "User Defined", "Takes an array of integers as an argument", "Vector of integ" "ers\000", "\0appscope=1\0", 1) extern "C" __declspec( dllexport ) LPXLOPER IntArray(const COper* A) { XLL_FIX_STATE; CXlOper xloResult; //}}XLP_SRC std::vector<int> vecA; if (!A->ReadVector(vecA, "A", xloResult)) return xloResult.Ret(); for (size_t i = 0; i < vecA.size(); i++) vecA[i] *= 2; xloResult.FromNumericVector(vecA); return xloResult.Ret(); }
Background
The reasons the XLL+ Function Wizard does not directly support type int
are historical.
-
First, the XLL+ toolkit was originally designed to work with both 16-bit and
32-bit Windows code. Integer type
int
was mapped to a 16-bit integer under 16-bit Windows and to a 32-bit integer under 32-bit environments. We decided to avoid theint
type since it would lead to confusion and to difficulties porting code between environments. Instead, we used the typeslong
,short
andunsigned short
, which were of consistent size under both 16-bit and 32-bit environments. (In addition, these types are supported internally by Excel.) -
Early versions of Microsoft C++ did not support the
bool
type, and instead used the typeBOOL
, which is typedef'ed as anint
. We therefore supported this type directly in the Function Wizard (and continue to do so). Inputs of typeBOOL
are automatically transformed from numbers to boolean values. SinceBOOL
andint
are the same, this means that variables of typeint
are treated as boolean values, rather than as integers.
In line with our overriding policy of not breaking code between XLL+ versions,
we have therefore continued to support the BOOL
type, at the
expense of the int
type.