Excel versions before Excel 2007 pass strings to add-in functions as ANSI strings of 255 characters or less. Excel 2007 passes Unicode strings of up to 32767 characters.
A portable XLL add-in must therefore be able to handle either type of string.
An add-in function generated by XLL+ uses two diffrent wrapper functions to handle being called from Excel 2003 and below and being called from Excel 2007 and above.
Each of the wrapper functions creates a portable object, of type CXlStringArg, which contains the string argument's value. The CXlStringArg object is passed to the common implementation function.
CXlStringArg is able to provide a Unicode string or an ANSI string, as the developer prefers.
You can use the CXlStringArg object anywhere that your
code needs a const char*
or const wchar_t*
string pointer.
The compiler will cast it as required, and the class will convert the data
between ANSI and Unicode as required.
If you have existing code which uses string arguments, it will
in general continue working under XLL+ 6.
The old version of the function had an argument of type
const char*
; the upgraded version will have
const CXlStringArg&
.
The compiler will use the casting operator
CXlStringArg::operator const char*
and the code will work as before.
A problem arises if your code passes the string to a loosely-typed function
such as printf()
or CXlOper::Format.
The code will compile successfully,
but the compiler will not invoke the casting operator, and you must cast the value explicitly.
For example, an XLL+ 5 add-in function with a string argument might use it as follows:
extern "C" __declspec( dllexport ) LPXLOPER GetCustomerDetails(const char* customer) { //}}XLP_SRC char select[512]; sprintf(select, "SELECT * FROM CUSTOMER WHERE NAME='%s'", customer); ... }
Under XLL+ 6 the converted code will fail, and the argument to
sprintf
must be cast to const char*
:
CXlOper* GetCustomerDetails_Impl(CXlOper& xloResult, const CXlStringArg& customer) { // End of generated code //}}XLP_SRC char select[512]; sprintf(select, "SELECT * FROM CUSTOMER WHERE NAME='%s'", (const char*)customer); ... }