class EL_DYNAMIC_MODULE_POINTERS
Dynamic module API function pointers. This class automates the process of assigning shared object (DLL) API function pointers to pointer attributes.
To use this class, define a descendant and define a pointer attribute for each API function. The attibute must be named to match the API name with any common prefix stripped from the beginning. A common prefix is defined by creating a descendant of EL_DYNAMIC_MODULE and defining a value for name_prefix. The name of the C function will be automatically inferred from the attribute names
In the make routine these pointer attributes will be automatically initialized, by inferring the C function names from the attribute names using object reflection.
Reserved Words
If the C function name happens to coincide with an Eiffel reserved word, create for example, the attribute name can be tweaked with addition of an underscore, create_ in this example. This will resolve any compilation problems. The C function name will still be correctly inferred.
Upper case letters
Any C function names that happen to contain uppercase characters, must be explicitly listed by redefining the array function function_names_with_upper. This is because Eiffel identifers are case-insensitive and the object reflection always returns the name in lowercase.
note
description: "[
Dynamic module API function pointers.
This class automates the process of assigning shared object (DLL) API function pointers to
pointer attributes.
]"
instructions: "[
To use this class, define a descendant and define a pointer attribute for each API function.
The attibute must be named to match the API name with any common prefix stripped from the beginning.
A common prefix is defined by creating a descendant of ${EL_DYNAMIC_MODULE} and defining a value for
`name_prefix'. The name of the C function will be automatically inferred from the attribute names
In the `make' routine these pointer attributes will be automatically initialized, by inferring the
C function names from the attribute names using object reflection.
**Reserved Words**
If the C function name happens to coincide with an Eiffel reserved word, `create' for example, the attribute
name can be tweaked with addition of an underscore, `create_' in this example. This will resolve any compilation
problems. The C function name will still be correctly inferred.
**Upper case letters**
Any C function names that happen to contain uppercase characters, must be explicitly listed by redefining
the array function `function_names_with_upper'. This is because Eiffel identifers are case-insensitive and
the object reflection always returns the name in lowercase.
]"
author: "Finnian Reilly"
copyright: "Copyright (c) 2001-2022 Finnian Reilly"
contact: "finnian at eiffel hyphen loop dot com"
license: "MIT license (See: en.wikipedia.org/wiki/MIT_License)"
date: "2024-01-20 19:18:25 GMT (Saturday 20th January 2024)"
revision: "18"
class
EL_DYNAMIC_MODULE_POINTERS
inherit
EL_REFLECTIVELY_SETTABLE
rename
foreign_naming as eiffel_naming
end
EL_MODULE_EXCEPTION
create
make
feature {NONE} -- Initialization
make (module: EL_DYNAMIC_MODULE [EL_DYNAMIC_MODULE_POINTERS])
-- Assumes that any pointer fields starting with "pointer_" correspond to an
-- API function name and that the remainder of the field name is the same as the
-- API name without the prefix defined by `name_prefix'
-- since Eiffel identifiers are case insensitive, C API identifiers with upper case characters must be
-- listed by overriding the function `function_names_with_upper'
local
names_with_upper: EL_HASH_TABLE [STRING, STRING]
name: STRING; function: POINTER
do
make_default
create names_with_upper.make_equal (11)
across function_names_with_upper as upper_name loop
names_with_upper [upper_name.item.as_lower] := upper_name.item
end
if attached field_table as table then
from table.start until table.after loop
name := table.key_for_iteration
if names_with_upper.has_key (name) then
name := names_with_upper.found_item
end
function := module.function_pointer (name)
if function = Default_pointer then
Exception.raise_developer (
"API initialization error. No such C routine %"%S%S%" in class %S",
[module.name_prefix, name, generator]
)
elseif attached {EL_REFLECTED_POINTER} table.item_for_iteration as pointer_field then
pointer_field.set (Current, function)
end
table.forth
end
end
end
feature {NONE} -- Implementation
field_included (field: EL_FIELD_TYPE_PROPERTIES): BOOLEAN
do
Result := field.is_pointer
end
function_names_with_upper: ARRAY [STRING]
-- List any C API names that contain uppercase characters in descendant
-- but strip the names of the general prefix defined by `name_prefix'
do
create Result.make_empty
end
end