in black and white
Main menu
Share a book About us Home
Biology Business Chemistry Computers Culture Economics Fiction Games Guide History Management Mathematical Medicine Mental Fitnes Physics Psychology Scince Sport Technics

Excel add in development in C++ Aplications in finance - Dalton S.

Dalton S. Excel add in development in C++ Aplications in finance - Wiley publishing , 2005. - 425 p.
ISBN 0-470-02469-0
Download (direct link): exceladdindevelopmentincand2005.pdf
Previous << 1 .. 23 24 25 26 27 28 < 29 > 30 31 32 33 34 35 .. 168 >> Next

CY c = some_function_that_returns_a_CY(some_argument);
double d = (double)(c.int64) / 1e4; // Divide to undo the scaling
You will encounter this data type when your C/C++ DLL is passed an array of VARIANTS by VB created from an Excel Range object’s Value property, where one or more cells in the Range have been formatted using the standard currency format for the regional settings in force at the time. This is mildly annoying: the value of a cell should be its underlying value regardless of the display format. (Excel and VB do a similar thing for worksheet cells formatted as dates.) If you are handling arrays of data originating in Excel worksheet ranges, you will need to deal with this data type. (See sections 3.6.9 Variant data type and 3.7 Excel ranges, VB arrays, SafeArrays, array Variants below for more detail and some example code.)
3.6.6 VB/OLE Strings
The VB String data type is an OLE data type defined for C/C++ as BSTR in <wtypes.h>. The BSTR is implemented as a pointer to a zero-terminated array of type unsigned short - a string of 16-bit wide characters. However, Excel passes and accepts null-terminated byte-strings. VBA for Excel understands this and stores the bytes of the string in the high and low bytes of the array pointed to by the BSTR.
For example, the text "Test string" passed from VB to a C/C++ function would be stored as shown in Table 3.3.
Table 3.3 Excel VBA string passed to C/C++: Example 1
Passed in as BSTR bstr Value (unsigned short) Value (byte string)
(*bstr) [0] 0x6554 ((char *)(*bstr))[0] = 0x54 = 'T' ((char *) (*bstr)) [1] = 0x65 = 'e'
(*bstr) [1] 0x7473 ( (char *) (*bstr) ) [2] = 0x73 = 's' ((char *)(*bstr))[3] = 0x74 = 't'
(*bstr) [2] 0x7320 ((char *)(*bstr))[4] = 0x20 = ' ' ((char *)(*bstr))[5] = 0x73 = 's'
(*bstr) [3] 0x7274 ((char *)(*bstr))[6] = 0x74 = 't' ((char *)(*bstr))[7] = 0x72 = 'r'
Using VBA 53
Table 3.3 (continued)
(*bstr)[4] 0x6e69 ((char *)(*bstr))[8] = 0x69 = 'i' ((char *)(*bstr))[9] = 0x6e = 'n'
(*bstr)[5] 0x0067 ((char *) (*bstr) ) [10] = 0x67 = 'g' ( (char *) (*bstr) ) [11] = 0x00 = Null termination of ANSI byte string
(*bstr) [6] 0x0000 Zero termination of BSTR string
The text "Test" would be stored as shown in Table 3.4.
Table 3.4 Excel VBA string passed to C/C++: Example 2
Passed in as BSTR bstr Value (unsigned short) Value (byte string)
(*bstr) [0] 0x6554 ((char *)(*bstr))[0] = 0x54 = 'T' ((char *)(*bstr))[1] = 0x65 = 'e'
(*bstr) [1] 0x7473 ((char *)(*bstr))[2] = 0x73 = 's' ((char *)(*bstr))[3] = 0x74 = 't'
(*bstr)[2] 0x0000 Zero termination of BSTR string and null termination of ANSI byte string combined
How long is a piece of string? As can be seen from these two examples, string length is dependent on what you are thinking of as the string. OLE provides two functions for determining the length of a BSTR: SysStringLen() and SysStringByteLen(). They would return the following when applied to these example strings:
Table 3.5 BSTR string length comparisons
String SysStringLen ( ) SysStringByteLen() Bytes allocated
Test string 6 11 14
Test 2 4 6
For strings of bytes passed in a BSTR from VB you should use SysStringByteLen().
Warning: When VB passes strings to C/C++ via a Variant argument of type VT_BSTR, the string is not a byte-string, but a null-terminated string of unsigned shorts. Care must be taken to distinguish between these two cases, as different system functions are required to read and create these. (See section 3.6.10 Variant types supported by VBA on page 58.)
Excel Add-in Development in C/C++
3.6.7 Passing strings to C/C++ functions from VB
When passed ByVal to C/C++ a VB String arrives as a BSTR. You could declare the argument as an unsigned short *. (Note that in doing this you would make your code dependent on the particular implementation of the BSTR type.) You can also declare your argument as char *, having the effect of casting the pointer directly to the memory allocated to the BSTR.
When passed ByRef a VB string arrives as a pointer to a BSTR, equivalent to a pointer to a pointer to an unsigned short, which you could declare as BSTR * or simply as unsigned short **. VB will always pass a non-null pointer to the BSTR. The pointer that this points to will be set to null if the string was declared in VB (using Dim) but not allocated a value. Consider the following piece of VB code:
' Argument is passed ByRef by default
Declare Function C_BSTR_Example1 Lib "example.xll" _
(s As String) As Boolean
Function VB_BSTR_EXAMPLE(Trigger As Variant) As Boolean
Dim s As String
' Call 1: String is dimensioned but not initialised C_BSTR_Example (s)
' Call 2: String is initialised to an empty string s = ""
C_BSTR_Example (s)
' Call 3:
s = "Test string"
C_BSTR_Example (s)
End Function
Suppose that the C/C++ function is prototyped as follows:
// Function definition corresponding to VB definition of // Declare Function C_BSTR_Example1 ...(s As String) As Boolean, // i.e. argument passed ByRef.
Previous << 1 .. 23 24 25 26 27 28 < 29 > 30 31 32 33 34 35 .. 168 >> Next