Вчера узнал, что ANSI C не разрешает приводить void* к указателю на функцию, даже явно, например код:
void *(*screngine_init)(void);
screngine_init = dlsym(screngine_lib, “screngine_init”);
(*screngine_call)(void);
будет не корректным.
Существует два варианта, как справиться с этой задачей:
- Использовать функцию dlfunc заместо dlsym.
- Использовать union такого вида: union { void *ptr; void (*call)(void); }
Использование dlfunc конечно хороший вариант, но эта функция есть не во всех системах, например на своём домашнем debian gnu/linux я её не обнаружил, хотя на соседних freebsd 6.0 она есть, поэтому я решил использовать union-метод, посчитав его более переносимым, тем более что он не на много сложнее варианта с вызовом dlfunc:
union { void *ptr; void (*call)(void); } screngine_init;
screngine_init.ptr = dlsym(screngine_lib, “screngine_init”);
screngine_init.call(void);
По моему даже красивее, чем в первоначальном варианте. :)