ShowTable of Contents
Using LotusScript C-Callouts on non-32-bit Platforms
There are a few issues you need to be aware of if you're writing or porting LotusScript C-Callouts to non-32-bit platforms.
The non-32-bit platforms fall into two categories: 64-bit (Windows 64, AIX-64, Linux-64) and 128-bit (iSeries)
When is a long not a long?
An important thing to consider is that LotusScript data types are the same size across all platforms. A LotusScript
byte is always one byte (a Notes
BYTE in C),
integer is always 2 bytes (a Notes
WORD in C) and a
long is always 4 bytes (a Notes
DWORD in C). In contrast, a C
long is not a fixed width across platforms, or even compilers. In the Notes 8 builds, a long is 4 bytes on Windows-64 and iSeries, but 8 bytes on AIX-64, SUSE Linux-64 and zLinux64.
In order to check how many bytes a long and a pointer is on a given platform, compile and run the following simple C program:
main()
{
printf("sizeof long is: %d, pointer is %d\n", sizeof (long), sizeof (long *));
}
LotusScript will take care of expanding C-Callout parameters that are 8-byte longs when passed by value, so a LotusScript long (4 bytes) will be expanded in the call to a native long (4 or 8-bytes). However, if you pass a value ByRef where the C-Callout is expecting an pointer to an 8-byte long, then you have to be very careful. The C-Callout (long *) will expect to be pointing to an 8-byte value, when in fact it's pointing to only 4 bytes (for a LotusScript long) allocated by LotusScript. Dereferencing the C-Callout 8-byte-long pointer can result in a memory overwrite that could result in a crash. You can partially get around that by passing a ByRef double LotusScript value to a (long *) C value (on platforms where a long is 8 bytes) since LotusScript will have allocated 8-bytes (the size of a LotusScript double) to point to. Then, on the C side, dereferencing the (long *) value will not cause a crash. However, on the LotusScript side you will not be able to reference or modify the double that was passed ByRef, since internally it's a different format than an 8-byte long. You can, however, pass it to another C-Callout that expects an 8-byte long value.
As an aside, a Notes
DHANDLE is 32 bits on all platforms except Solaris and AIX-32, where it's 16 bits.
There were some bugs in C-Callouts on 64-bit platforms that have been fixed in Notes/Domino 8.5.2.
Pointers
Pointers are a more straightforward issue (except on iSeries). On all 64-bit platforms, you can pass and return 8-byte pointers by using the LotusScript
double datatype. However, you
cannot manipulate these objects on the LotusScript side. Your C-Callout can return a pointer in a double, and then in LotusScript you can call another C-Callout with the double parameter to a C pointer, but you must not change the value of the double in LotusScript. This is the same scheme you can use to pass a pointer to an 8-byte long integer value described above.
iSeries has it's own issue in that pointers are 16-bytes long. Since no LotusScript data type is that big, you cannot pass pointers or return pointers via C-Callouts on iSeries.