Passing arrays, types, and objects
Passing arrays as arguments
Because LotusScript® stores an array in a private format, you can pass an array by reference to a C function only if the function is specifically written for LotusScript®. The following example shows how to declare and implement a C function that takes a LotusScript® array of long values.
In LotusScript®:
Declare Function LSArrayArg Lib "MYDLL" (ArrLng () As Long)_
As Long
Dim MyArr(0 to 5) As Long
Print LSArrayArg(MyArr)
In C:
long C_CALL_TYPE LSArrayArg(LSsValueArray *pLSArr)
{
long *pData=pLSArr->Data;
//pData points to first array element
return pData[0]+pData[1]; //Sum first 2 array elements
}
Or:
long C_CALL_TYPE LSArrayArg(long **pLSArr)
{
long *pData=*pLSArr;
//pData points to first array element
return pData[0]+pData[1]; //Sum first 2 array elements
C_CALL_TYPE is the calling convention: Pascal, STDCALL, _System, or CDECL.
Other C functions may require an array, such as the Windows™ function SetBitmapBits. You can still pass the array by passing the first array element by reference with the Any keyword, as shown in the following example.
In LotusScript®:
Declare Function FncArrayArg(A As Any) As Long
Dim MyArr(0 to 5) As Long
Print FncArrayArg(MyArr(0))
In C:
long C_CALL_TYPE FncArrayArg(long *pArr)
{
return pArr[0]+pArr[1]; //Sum first 2 array elements
}
Passing types as arguments
Some C functions can require a data structure as a parameter. An example is the Windows™ API function GetBrushOrgEx, which requires a pointer to a point structure. You can define a suitable data type, such as Point, and use that type definition to declare the C function. Since type variables are passed by reference, the C function receives a 4-byte pointer to the storage for the type variable.
LotusScript® allows you to specify an optional string type, Unicode or LMBCS, on a type parameter in the Declare statement for a C function. The declarations have this form, for a function UniTest with one type argument and a function LMBCSTest with one type argument, where t1 is a user-defined data type:
Declare Function UniTest Lib "Unilib" (typArg As Unicode t1)_
As Long
Declare Function LMBCSTest Lib "lmbcslib" _
(typArg As LMBCS t1) As Long
In the first example, all strings (fixed-length and variable-length) in type t1 and any of its nested types will be passed as Unicode strings. In the second example, all strings in type t1 (fixed- and variable-length) and any of its nested types will be passed as LMBCS strings.
If Unicode or LMBCS is not specified in this way, the default is to pass all strings in a type argument in the platform-native character set. This is compatible with LotusScript® Release 2.
Strings contained in Variants in the type will not be affected. This change is incompatible with LotusScript® Release 2, because translation to platform will be invoked by default on types containing strings (previously, these strings would have been passed as platform-native character set strings).
If the type contains a fixed-length non-Unicode string, the entire structure must be copied and its size adjusted. The size of the structure will be smaller (each fixed-length string will contain half as many bytes when translated to platform or LMBCS, since the length of the string is fixed and must be preserved). This implies that the string may be truncated (lose information) because a Unicode string of length 20 may require more than 20 bytes to represent in platform (DBCS). The loss cannot occur with variable-length strings, since they are represented as pointers.
LotusScript® aligns type members to their natural boundaries for cross-platform transportability:
Data type |
Alignment |
---|---|
Boolean |
2 bytes |
Byte |
1 byte |
Integer |
2 bytes |
Long |
4 bytes |
Single |
4 bytes |
Double |
8 bytes |
Currency |
4 bytes |
String (LMBCS) |
2 bytes |
String (Unicode) |
2 bytes |
String (Platform) |
1 byte |
Variant |
8 bytes |
The resulting alignment will not match the platform-specific alignment on Windows™ 3.1 and Windows™ 95. For example, LotusScript® aligns the type member B on a 4-byte boundary, while the default alignment in Windows™ 3.1 will be on a 2-byte boundary.
Type telMet
A As Integer
B As Long
End Type
Passing objects as arguments
When an object is passed to a C function, the function receives a 4-byte pointer to the unpacked data in the object. Because the data may include pointers to strings, arrays, lists, and product objects, it is unlikely that the C function has full knowledge of the internal structure of the object. You should use a C function to manipulate only the simplest objects.
Example 1
' The following statements declare the C function
' SetBitmapBits.Its 3rd argument is an array argument. This is
' declared as type Any. In the function call, passing
' bitArray(0) passes the array by reference.
Declare Sub SetBitmapBits Lib "_privDispSys" _
(ByVal hBM As Integer, ByVal cBytes As Long, pBits As Any)
' ...
SetBitmapBits(hBitmap, cBytesInArray, bitArray(0))
Example 2
type mytype
mName as string
end type
class myclass
mName as string
end class
function VariantParam( v as Variant) as string
dim tempstr as string
tempstr = TypeName(v)
VariantParam = tempstr
end function
sub initialize
dim myinteger as integer
dim mylong as long
dim mystring as string
dim myintlist list as integer
dim myintarray() as integer
dim mymytype as mytype
dim mymyclass as myclass
messagebox variantparam(myintlist)
messagebox variantparam(myintarray)
' Error: Type mismatch on: MYMYTYPE
' messagebox variantparam(mymytype)
messagebox variantparam(mymyclass)
end sub