Lugaru's Epsilon
Programmer's
Editor

Context:
Epsilon User's Manual and Reference
   Primitives and EEL Subroutines
      . . .
      File Primitives
         File Reading Primitives
         File Writing Primitives
         Line Translation Primitives
         . . .
         Tagging Internals
      Operating System Primitives
         . . .
         Window System Primitives
         Timing
         Calling Windows DLLs
         Running a Process
      Control Primitives
         Control Flow
         Character Types
         Examining Strings
         . . .
         Help Subroutines
      . . .

Previous   Up    Next
Timing  Primitives and EEL Subroutines   Running a Process


Epsilon User's Manual and Reference > Primitives and EEL Subroutines > Operating System Primitives >

Calling Windows DLLs

int call_dll(char *dll_name, char *func_name,
             char *ftype, char *args, ...)

The call_dll( ) primitive calls a function in a Windows DLL. Epsilon can only call 32-bit DLLs. The dll_name parameter specifies the DLL file name. The func_name parameter specifies the name of the particular function you want to call.

The ftype parameter specifies the routine's calling convention. The character C specifies the C calling convention, while P specifies the Pascal calling convention. Most Windows DLLs use the Pascal calling convention, but any function that accepts a variable number of parameters must use the C calling convention.

The args parameter specifies the type of each remaining parameter. Each letter in args specifies the type of one parameter, according to the following table.

 Character  Description  
 L  unsigned long  DWORD
 I  int  INT, UINT, HWND, most other handles
 S  far char *  LPSTR
 P  far void *  LPVOID
 R  far void **  LPVOID *

The I character represents a 32-bit parameter, and is equivalent to L in this version. L, S, P, and R always represent 32-bit parameters.

S represents a null-terminated string being sent to the DLL. P is passed similarly, but Epsilon will not check the string for null termination. It's useful when the string is an output parameter of the DLL, and may not be null-terminated before the call, or when passing structure pointers to a DLL.

R indicates that a DLL function returns a pointer by reference. Epsilon will pass the pointer you supply (if any) and retrieve the result. Use this for DLL functions that require a pointer to a pointer, and pass the address of any EEL variable whose type is "pointer to ..." (other than "pointer to function").

Here's an example, using call_dll( ) to determine the main Windows directory:

#define GetWindowsDirectory(dir, size)  (is_gui == IS_WIN31 \
    ? call_dll("kernel.dll", "GetWindowsDirectory", \
               "p", "pi", dir, size) \
    : call_dll("kernel32.dll", "GetWindowsDirectoryA", \
               "p", "pi", dir, size))

    char dir[FNAMELEN];

    GetWindowsDirectory(dir, FNAMELEN);
    say("The Windows directory is %s", dir);

A DLL function that exists in both 16-bit and 32-bit environments will usually be in different .dll files, and will often go by a different name. Its parameters will often be different as well. In particular, remember that a structure that includes int members will be a different size in the two environments. To write an EEL interface to a DLL function that takes a pointer to such a structure, you'll need to declare two different versions of the structure, and pass the correct one to the DLL function, if you want your EEL interface to work in both 16-bit and 32-bit environments.

After you call a function in a DLL, Epsilon keeps the DLL loaded to make future calls fast. You can unload a DLL loaded by call_dll( ) by including just the name of the DLL, and omitting the name of any function or parameters. For example, call_dll("extras.dll"); unloads a DLL named extras.dll.

char *make_pointer(int value)

The make_pointer( ) primitive can be useful when interacting with system DLLs. It takes a machine address as a number, and returns an EEL pointer that may be used to access memory at that address. No error checking will be done on the validity of the pointer.



Previous   Up    Next
Timing  Primitives and EEL Subroutines   Running a Process


Lugaru Copyright (C) 1984, 2020 by Lugaru Software Ltd. All rights reserved.