Указатели на функции: * (void **) (& amp; fun) = dlsym (lib, & quot; fun & quot;) как это работает?

Я использую dlsym для заполнения указателя на функцию, которая является переменной-членом вызова.
как ниже

class ABC {
private:
void (*m_fun) (int);
}

сейчас, если я назначу

m_fun = (void*) dlsym (libHandle, "fun")

Это дает ошибку

Через интернет я нашел

*(void**) (&m_fun) = dlsym(libHandle, "fun") is working.

Может кто-нибудь сказать мне, как это преобразование / кастинг происходит здесь?

2

Решение

Актерский состав говорит:

  • взять указатель на функцию
  • получить указатель на это
  • делать вид, что указатель указывает на обычный указатель объекта (void*) не указатель на функцию
  • напишите адрес, возвращенный dlsym хотя этот указатель, тем самым устанавливая указатель функции на этот адрес

Это работает вокруг (обычно желательного) ограничения, что вы не можете назначить указатель функции на указатель объекта. Так как это C ++, вы можете написать его так:

reinterpret_cast<void*&>(m_fun) = dlsym(libHandle, "fun");

что может быть немного яснее: притворяться m_fun это void*и напиши ему.

Обратите внимание, что это менее переносимо, чем преобразование результата dlsym правильному типу и присвоив его:

m_fun = reinterpret_cast<void(*)(int)>(dlsym(libHandle, "fun"));

которая либо будет работать правильно, либо выдаст ошибку компилятора на любой платформе. Ваш более хитрый бросок может привести к неопределенному поведению во время выполнения на платформах с неоднородной архитектурой памяти.

4

Другие решения

Void * это просто указатель памяти. Чтобы использовать указатель функции для указания на функцию, сначала необходимо указать указатель на фактическую функцию, а остальная часть указателя (**) должна указывать на переменные и тело функции.

0

По вопросам рекламы [email protected]