forked from enlightenment/efl
Eo: Add function name to OP desc on Windows
Match function names when the API pointer is out of range. Reviewed by TAsn and modified according to his comments :) Differential Revision: https://phab.enlightenment.org/D876
This commit is contained in:
parent
0405d8e9a5
commit
02f24d76e1
|
@ -368,6 +368,9 @@ typedef enum _Eo_Class_Type Eo_Class_Type;
|
|||
typedef struct _Eo_Op_Description
|
||||
{
|
||||
void *api_func; /**< The EAPI function offering this op. */
|
||||
#ifdef _WIN32
|
||||
const char *api_name; /**< Full name of this API entry-point. Used to work around import indirection in DLL's. */
|
||||
#endif
|
||||
void *func; /**< The static function to call for the op. */
|
||||
Eo_Op op; /**< The op. */
|
||||
Eo_Op_Type op_type; /**< The type of the Op. */
|
||||
|
@ -547,11 +550,17 @@ EAPI extern Eo_Hook_Call eo_hook_call_post;
|
|||
// OP ID of an overriding function
|
||||
#define EO_OP_OVERRIDE ((Eo_Op) -1)
|
||||
|
||||
#define EO_OP_FUNC(_api, _private, _doc) {_api, _private, EO_NOOP, EO_OP_TYPE_REGULAR, _doc}
|
||||
#define EO_OP_CLASS_FUNC(_api, _private, _doc) {_api, _private, EO_NOOP, EO_OP_TYPE_CLASS, _doc}
|
||||
#define EO_OP_FUNC_OVERRIDE(_api, _private) {_api, _private, EO_OP_OVERRIDE, EO_OP_TYPE_REGULAR, NULL}
|
||||
#define EO_OP_CLASS_FUNC_OVERRIDE(_api, _private) {_api, _private, EO_OP_OVERRIDE, EO_OP_TYPE_CLASS, NULL}
|
||||
#define EO_OP_SENTINEL { NULL, NULL, 0, EO_OP_TYPE_INVALID, NULL}
|
||||
#ifndef _WIN32
|
||||
# define _EO_OP_API_ENTRY(a) a
|
||||
#else
|
||||
# define _EO_OP_API_ENTRY(a) a, #a
|
||||
#endif
|
||||
|
||||
#define EO_OP_FUNC(_api, _private, _doc) { _EO_OP_API_ENTRY(_api), _private, EO_NOOP, EO_OP_TYPE_REGULAR, _doc }
|
||||
#define EO_OP_CLASS_FUNC(_api, _private, _doc) { _EO_OP_API_ENTRY(_api), _private, EO_NOOP, EO_OP_TYPE_CLASS, _doc }
|
||||
#define EO_OP_FUNC_OVERRIDE(_api, _private) { _EO_OP_API_ENTRY(_api), _private, EO_OP_OVERRIDE, EO_OP_TYPE_REGULAR, NULL }
|
||||
#define EO_OP_CLASS_FUNC_OVERRIDE(_api, _private) { _EO_OP_API_ENTRY(_api), _private, EO_OP_OVERRIDE, EO_OP_TYPE_CLASS, NULL }
|
||||
#define EO_OP_SENTINEL { _EO_OP_API_ENTRY(NULL), NULL, 0, EO_OP_TYPE_INVALID, NULL }
|
||||
|
||||
// returns the OP id corresponding to the given api_func
|
||||
EAPI Eo_Op _eo_api_op_id_get(const void *api_func, const char *file, int line);
|
||||
|
|
|
@ -685,7 +685,7 @@ end2:
|
|||
|
||||
|
||||
static inline const Eo_Op_Description *
|
||||
_eo_api_desc_get(const void *api_func, const _Eo_Class *klass, const _Eo_Class **extns)
|
||||
_eo_api_desc_get(const void *api_func, const _Eo_Class *klass, const _Eo_Class **extns, const char *api_name)
|
||||
{
|
||||
int imin, imax, imid;
|
||||
const _Eo_Class *cur_klass;
|
||||
|
@ -715,6 +715,22 @@ _eo_api_desc_get(const void *api_func, const _Eo_Class *klass, const _Eo_Class *
|
|||
return op_desc;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* On Windows, DLL API's will be exported using the dllexport flag.
|
||||
* When used by another library or executable, they will be declared
|
||||
* using the dllimport flag. What happens really is that two symbols are
|
||||
* created, at two different addresses. So it's impossible to match
|
||||
* them. We fallback to plain string comparison based on the
|
||||
* function name itself. Slow, but this should rarely happen.
|
||||
*/
|
||||
for (int i = 0; i < cur_klass->desc->ops.count; i++)
|
||||
if (op_descs[i].api_name && !strcmp(api_name, op_descs[i].api_name))
|
||||
{
|
||||
if (op_descs[i].api_func == NULL || op_descs[i].api_func == ((void (*)())-1))
|
||||
break;
|
||||
return &op_descs[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -723,7 +739,7 @@ _eo_api_desc_get(const void *api_func, const _Eo_Class *klass, const _Eo_Class *
|
|||
for (kls_itr = extns ; *kls_itr ; kls_itr++)
|
||||
{
|
||||
cur_klass = *kls_itr;
|
||||
op_desc = _eo_api_desc_get(api_func, cur_klass, NULL);
|
||||
op_desc = _eo_api_desc_get(api_func, cur_klass, NULL, api_name);
|
||||
if (op_desc) return op_desc;
|
||||
}
|
||||
}
|
||||
|
@ -748,7 +764,10 @@ _eo_api_op_id_get(const void *api_func, const char *file, int line)
|
|||
else
|
||||
klass = stack->frame_ptr->o.obj->klass;
|
||||
|
||||
desc = _eo_api_desc_get(api_func, klass, klass->extensions);
|
||||
// Win32 compatibility: api_name is NULL because we're assuming the
|
||||
// function pointer is correct (it was referred to using the same
|
||||
// dllimport vs. dllexport flags).
|
||||
desc = _eo_api_desc_get(api_func, klass, klass->extensions, NULL);
|
||||
|
||||
if (desc == NULL)
|
||||
{
|
||||
|
@ -819,7 +838,11 @@ _eo_class_funcs_set(_Eo_Class *klass)
|
|||
}
|
||||
else if (op_desc->op == EO_OP_OVERRIDE)
|
||||
{
|
||||
api_desc = _eo_api_desc_get(op_desc->api_func, klass->parent, klass->extensions);
|
||||
#ifdef _WIN32
|
||||
api_desc = _eo_api_desc_get(op_desc->api_func, klass->parent, klass->extensions, op_desc->api_name);
|
||||
#else
|
||||
api_desc = _eo_api_desc_get(op_desc->api_func, klass->parent, klass->extensions, NULL);
|
||||
#endif
|
||||
|
||||
if (api_desc == NULL)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue