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
ReadVectorfails (i.e. returns FALSE), return the error information which is placed intoxloResultbyReadVector.
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
intwas mapped to a 16-bit integer under 16-bit Windows and to a 32-bit integer under 32-bit environments. We decided to avoid theinttype since it would lead to confusion and to difficulties porting code between environments. Instead, we used the typeslong,shortandunsigned 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
booltype, 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 typeBOOLare automatically transformed from numbers to boolean values. SinceBOOLandintare the same, this means that variables of typeintare 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.
