| Home | Previous Lesson: Stored Procedures - External Functions Next Lesson: Summary |
If you are targeting an application for multi platforms, make sure that equivalent DLLs are available on the target platform(s). If you are using operating system specific APIs, you need to write C functions on other platforms.
If you are targeting the application for MS-windows 16-bit as well as 32-bit operating systems, remember that some function and DLL names are different in them. For example, for multimedia, you need to call mciSendString() under 16-bit, but, you need to call mciSendStringA() under 32-bit. MMSystem.dll is the DLL for the former one where as winmm.dll is the DLL for the later one. To solve this problem, use inheritance and user objects and virtual functions.
To make this happen, create a base class user object. In this base user object create dummy function calls with the exact names, argument lists, and the return values you want. For example, for the above situation, we can create a function, uf_mciSendString. These calls can be dummy, as they will never be called. Here, the function names, argument lists and return values are important and must be defined exactly as you need them.
Next, create two class user objects by inheriting from this base object. One for Win 3.1 (say uo_16_bit) and one for Win NT/95 (say uo_32_bit). In each of these, encapsulate the functions with the same names, argument lists and return values as its ancestor. Declare local external functions in uo_16_bit, say, mciSendString(), and similarly, declare local external functions in uo_32_bit, say, mciSendStringA().Because they are local for each object the definitions can be the same, without any collision (in fact function names must be same)
At run time, declare a variable of the base (uo_api) user object. Then check the environment by calling GetEnvironment function and instantiate the appropriate user object's instance. All calls to the code refer to the variable and thus call the function in the instantiated user object.
Since the variable is of ancestor type, you only get the attributes and methods that are defined for the ancestor. That is why it is important that you have dummy definitions in the base NVO with the same name and argument types. At run time, they will be overridden by functions with the same name in the instantiated descendent NVO and you get the environment functions that you need.
The following example explains this technique. (This following code snippet is from the example application)
// Get the operating system type. This will be stored
// in a global variable. Examples will reference this
// to determine if they can perform certain
// OS specific functions.
environment le_environment
u_external_function luo_ef
GetEnvironment(le_environment)
Choose case le_environment.ostype
Case Windows!
luo_ef = create uo_16_bit
Case Windowsnt!
luo_ef = create uo_32_bit
Case Else
SetNull(luo_ef)
End Choose
Return luo_ef
| Home | Previous Lesson: Stored Procedures - External Functions Next Lesson: Summary |