updating oE define_c_func


include dll.e 
namespace dll 
public function define_c_func(object lib, object routine_name, sequence arg_types, 
        atom return_type) 

defines the characteristics of either a C function, or a machine-code routine that returns a value.

  1. lib : an object, either an entry point returned as an atom by open_dll, or "" to denote a routine the RAM address is known.
  2. routine_name : an object, either the name of a procedure in a shared object or the machine address of the procedure.
  3. argtypes : a sequence of type constants.
  4. return_type : an atom, indicating what type the function will return.

A small integer, known as a routine id, will be returned.


The length of name should not exceed 1_024 characters.


Use the returned routine id as the first argument to c_proc when you wish to call the routine from Euphoria.

A returned value of -1 indicates that the procedure could not be found or linked to.

On Windows you can add a '+' character as a prefix to the function name. This indicates to Euphoria that the function uses the cdecl calling convention. By default, Euphoria assumes that C routines accept the stdcall convention.

When defining a machine code routine, x1 must be the empty sequence ( "" or {}), and x2 indicates the address of the machine code routine. You can poke the bytes of machine code into a block of memory reserved using allocate. On Windows the machine code routine is normally expected to follow the stdcall calling convention, but if you wish to use the cdecl convention instead, you can code {'+', address} instead of address for x2.

The C function that you define could be one created by the Euphoria To C Translator, in which case you can pass Euphoria data to it, and receive Euphoria data back. A list of Euphoria types is contained in dll.e:

  • E_INTEGER = #06000004
  • E_ATOM = #07000004
  • E_SEQUENCE= #08000004
  • E_OBJECT = #09000004

You can pass or return any C integer type or pointer type. You can also pass a Euphoria atom as a C double or float, and get a C double or float returned to you as a Euphoria atom.

Parameter types which use 4 bytes or less are all passed the same way, so it is not necessary to be exact when choosing a 4-byte parameter type. However the distinction between signed and unsigned may be important when you specify the return type of a function.

Currently, there is no way to pass a C structure by value or get a C structure as a return result. You can only pass a pointer to a structure and get a pointer to a structure as a result. However, you can pass a 64 bit integer as two C_LONG instead. On calling the routine, pass low doubleword first, then high doubleword.

If you are not interested in using the value returned by the C function, you should instead define it with define_c_proc and call it with c_proc.

If you use euiw to call a cdecl C routine that returns a floating-point value, it might not work. This is because the Watcom C compiler (used to build euiw) has a non-standard way of handling cdecl floating-point return values.

Passing floating-point values to a machine code routine will be faster if you use c_func rather than call to call the routine, since you will not have to use atom_to_float64 and poke to get the floating-point values into memory.

Example 1:
atom user32 
integer LoadIcon 
-- open user32.dll - it contains the LoadIconA C function 
user32 = open_dll("user32.dll") 
-- It takes a C pointer and a C int as parameters. 
-- It returns a C int as a result. 
LoadIcon = define_c_func(user32, "LoadIconA", 
                         {C_POINTER, C_INT}, C_INT) 
-- We use "LoadIconA" here because we know that LoadIconA 
-- needs the stdcall convention, as do 
-- all standard .dll routines in the WINDOWS API.  
-- To specify the cdecl convention, we would have used "+LoadIconA". 
if LoadIcon = -1 then 
    puts(1, "LoadIconA could not be found!\n") 
end if 
See Also:

demo\callmach.ex, c_func, define_c_proc, c_proc, open_dll

Not Categorized, Please Help


Quick Links

User menu

Not signed in.

Misc Menu