Вопрос: Есть ли способ применить указатель на функцию-член к intptr_t в C++?Указатель на функцию-член для intptr_t
Известные факторы:
- Я знаю, что указатель функции члена очень специальный один
- Я знаю, что функция члена проходит скрытый «этот» параметр (__thiscall).
- Я знаю, что sizeof (указатель функции-члена)> sizeof (intptr_t) в некоторых случаях, в этом вопросе Я говорю только о том, где это возможно, то есть в моем случае sizeof (указатель функции-функции) == SizeOf (intptr_t).
- И, наконец, я знаю, что указатели каста на intptr_t не являются хорошим шаблоном.
Пример кода:
class test // No inheritance, in the case I need
{
public:
void func(); // No virtual, or any special modifiers in the case I need
};
void main2()
{
intptr_t p = &test::func;
};
Я знаю, обходной путь, чтобы сделать этот бросок, но я не люблю его, так как он requeres переменную TEMP:
void my_way()
{
intptr_t p;
auto t = &test::func; // Temp variable, I don't like the fact I need to use it, but I have no other way for now
p = *reinterpret_cast<intptr_t*>(&t);
};
Так вопрос как сделать трюк inline как выражение rvalue, без переменной temp (и без memcpy, которая является тем же самым).
Пример:
reinterpret_cast<??>(???_cast<??>(???_cast<??>(&test::func)))
(я не забочусь о том, как красиво выражение будет).
------------------------- (ниже некоторые мысли о том, почему, а не вопрос) ---------- ----------------------
На этом сайте есть несколько похожих тем, но все они в основном говорят о том, «почему вы так делаете?», или «зачем вам это нужно?», и говорить об этом решает проблему для того, кто спрашивает, но не для меня.
Зачем мне этот персонал: Я пишу какую-то задачу, где я решил реализовать свой собственный механизм для динамической компоновки. Может быть несколько конкретных приложений.
В моем случае - механизм динамической связи - я хочу передать указатель на функцию другому модулю. У меня есть класс и интерфейс как отдельная структура (я знаю, есть библиотеки с таким же подходом). Все классы, использующие этот механизм, как известно, равны (никакого наследования вообще нет, поэтому нет виртуальных и т. Д.). Все это работает на x86 32 бит или не более 64 Windows, скомпилированных MSVC 2012. Поскольку интерфейс полностью изолирован от класса, он использует массив указателей. Lib передает массив в хост-процесс. И в процессе пребывания у меня это ... Это даже не «проблема», но все-таки:
inline int my_interface::func_name(int param)
{
decltype(&interface_name::func_name) temp;
*((intptr_t*)&temp) = reinterpret_cast<interface_name::funcs*>(interface_desc->funcs)->func_name;
return (reinterpret_cast<decltype(this)>(object)->*temp)(param);
};
Это встроенная функция, поэтому я хочу, чтобы это было как можно меньше, и если это возможно, я хотел бы исключить «temp», потому что я не уверен, что компилятор правильно устранит это, даже при всех оптимизации.
Другие приложения (гипотонические): - Что делать, если я хочу защитить страницу памяти, где моя функция-член находится с определенным защитником. WinAPI дает мне способ сделать это, но для этого нужен адрес страницы. Нет проблем сделать это для нормальной работы, но для участника - только с WA, которую я описал? Или есть способ? - Что делать, если я хочу исправить изображение во время выполнения? То есть найти константу и заменить ее другим? Могут быть по крайней мере несколько причин для исправления времени выполнения: процесс миграции динамических связей 2.1, обфускация кода 2.2.
Это только для заметки - читатели часто спрашивают «зачем», я не хочу обсуждать, почему, потому что, на мой взгляд, может быть много приложений, все они не для новичков, а для парней безопасности и т. д.
Я прошу не обсуждать «Зачем это делать?», «Почему бы не использовать существующий механизм для dll/boost/других libs/других языков?» в этой теме.
Следует отметить, что есть дополнительный фактор: ли SizeOf (мфу) == SizeOf (intptr_t) будет зависеть от компилятора вы используете, не только типы , Посмотрите, согласен ли ваш компилятор с промежуточным нажатием на '(void *)', но вы по своему усмотрению, насколько это верно. – Mat
Это не может быть сделано с помощью кастинга: Pointer-to-members могут быть переданы только другим указателям-членам, даже с 'reinterpret_cast'. К сожалению, нет ничего, что можно было бы процитировать, поскольку в стандарте указывается только, какие приведения * разрешены. Однако вы могли бы использовать «memcpy» указателя на элемент (то есть скопировать содержимое указателя на член с помощью указателя на указатель на элемент). – dyp
Учитывая вашу собственную точку №4, вы можете объяснить * почему * вы хотите сделать это в любом случае? Например, пытаетесь ли вы найти способ создания универсального контейнера для mfps для произвольных объектов? – kfsone