Приведение указателей на функции в C ++

Официальные документы.

urllib.unquote( string )

Заменить %xx escape на их односимвольный эквивалент.

Пример: unquote('/%7Econnolly/') дает '/~connolly/'.

blockquote>

И затем просто декодирует.


Обновить : Для Python 3 напишите следующее:

urllib.parse.unquote(url)

Python 3 docs.

37
задан A-Sharabiani 16 July 2017 в 23:37
поделиться

2 ответа

Преобразование void * в указатель функции напрямую не допускается (не должно компилироваться с использованием каких-либо преобразований) в C ++ 98 / 03. Это условно поддерживается в C ++ 0x (реализация может выбрать определение поведения, и если оно действительно определяет его, тогда она должна делать то, что говорит стандарт. A void * , как определено стандарт C ++ 98/03 предназначался для указания на объекты, а не для того, чтобы содержать указатели функций или указатели членов.

Зная, что то, что вы делаете, сильно зависит от реализации, вот один вариант, который должен компилироваться и работать (при условии 32-битные указатели, используйте long long для 64-битных) на большинстве платформ, хотя это явно неопределенное поведение в соответствии со стандартом:

void *gptr = dlsym(some symbol..) ;
typedef void (*fptr)();
fptr my_fptr = reinterpret_cast<fptr>(reinterpret_cast<long>(gptr)) ;

И вот еще один вариант, который должен компилироваться и работать, но содержит те же предостережения, что и предыдущий:

fptr my_ptr = 0;
reinterpret_cast<void*&>(my_ptr) = gptr; 

Или, в замедленном движении ...

// get the address which is an object pointer
void (**object_ptr)() = &my_ptr;  

// convert it to void** which is also an object pointer
void ** ppv = reinterpret_cast<void**>(object_ptr);

// assign the address in the memory cell named by 'gptr' 
// to the memory cell that is named by 'my_ptr' which is
// the same memory cell that is pointed to 
// by the memory cell that is named by 'ppv'
*ppv = gptr;  

По сути, он использует тот факт, что адрес указателя функции является указателем на объект ( void (** object_ptr ) () ) - поэтому мы можем использовать reinterpret_cast , чтобы преобразовать его в любой другой указатель на объект: например, void ** . Затем мы можем проследить адрес обратно (путем разыменования void ** ) на фактический указатель функции и сохранить там значение gptr.

yuk - ни в коем случае не четко определенный код - но он должен делать то, что вы ожидаете от него, в большинстве реализаций.

// get the address which is an object pointer
void (**object_ptr)() = &my_ptr;  

// convert it to void** which is also an object pointer
void ** ppv = reinterpret_cast<void**>(object_ptr);

// assign the address in the memory cell named by 'gptr' 
// to the memory cell that is named by 'my_ptr' which is
// the same memory cell that is pointed to 
// by the memory cell that is named by 'ppv'
*ppv = gptr;  

По сути, он использует тот факт, что адрес указателя функции является указателем на объект ( void (** object_ptr) () ) - поэтому мы можем использовать reinterpret_cast для его преобразования. на любой другой указатель объекта: например, void ** . Затем мы можем проследить адрес обратно (путем разыменования void ** ) на фактический указатель функции и сохранить там значение gptr.

yuk - ни в коем случае не четко определенный код - но он должен делать то, что вы ожидаете от него, в большинстве реализаций.

// get the address which is an object pointer
void (**object_ptr)() = &my_ptr;  

// convert it to void** which is also an object pointer
void ** ppv = reinterpret_cast<void**>(object_ptr);

// assign the address in the memory cell named by 'gptr' 
// to the memory cell that is named by 'my_ptr' which is
// the same memory cell that is pointed to 
// by the memory cell that is named by 'ppv'
*ppv = gptr;  

По сути, он использует тот факт, что адрес указателя функции является указателем на объект ( void (** object_ptr) () ) - поэтому мы можем использовать reinterpret_cast для его преобразования. на любой другой указатель объекта: например, void ** . Затем мы можем проследить адрес обратно (путем разыменования void ** ) на фактический указатель функции и сохранить там значение gptr.

yuk - ни в коем случае не четко определенный код - но он должен делать то, что вы ожидаете от него, в большинстве реализаций.

50
ответ дан 27 November 2019 в 03:47
поделиться

Это может вам помочь. Он печатает «Привет».

#include <iostream>

void hello()
{
  std::cout << "Hello" << std::endl;
}

int main() {
  typedef void (*fptr)();
  fptr gptr = (fptr) (void *) &hello;
  gptr();
}

ИЛИ вы можете сделать:

fptr gptr = reinterpret_cast<fptr>( (void *) &hello);

где & hello заменяется командой dlsym.

-6
ответ дан 27 November 2019 в 03:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: