Liberty BASIC 4 provides us with some great facilities for calling external code written in another language, such as C, if the non-LB code is compiled to a standard DLL. LB can pass these functions 16- and 32-bit integers (signed or unsigned), 64-bit (double-precision) real numbers, pointers to the same, and strings and structs.

The Problem

Where LB fails us is in calls using a 32-bit (single-precision) real number. C-derived languages call this a "float". While the Windows API uses very few FP data types, many third-party DLLs use them, and some use them a lot.

Some inexperienced LB-ers, upon encountering "float", simply regard it as a synonym for "double" and translate it into their LB code as such. Inexplicably, sometimes this works, but much more often the program fails--sometimes spectacularly.

The Solution

The "oleaut32" DLL that ships with Windows provides many functions for converting one data type to another. Two of these functions--"VarR4FromR8" and "VarR8FromR4"--look like they will fill the bill. The former converts a double to a float, and the latter converts it back to double.

The reader is probably scratching his or her head right now. "If LB doesn't have a single-precision type, how does a function that returns that type help?," you might ask.

As stated above, a float is 32 bits (4 bytes) in width. This is the same size as a "long" or "ulong" in LB. We can "pretend" these types are the same and use ulong in our LB code wherever a float is required, then use the conversion functions to give LB a type it can use.

The conversion functions are wrapped in two easy-to-use LB functions below.

In a CallDLL, make sure you are passing a variable because a numeric literal won't work.

When a float needs to be passed to a function or assigned to a struct element, convert the value to pseudo-float/ulong by wrapping the value in a call to toFloat.

When a function returns a float or modifies a struct with float, convert the value to true floating-point by wrapping the value in a call to fromFloat.

Simple Example

The following code demonstrates the conversion process. It calculates the value of pi, which is a type double. Then it converts it to an integer containing the same bits a float would. Finally, the value is converted to a double, but retains the same precision as a float.