Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.89/19: Рейтинг темы: голосов - 19, средняя оценка - 4.89
155 / 9 / 2
Регистрация: 14.08.2019
Сообщений: 771

Как будет &(PVOID&) в reinterpret_cast?

21.08.2021, 03:27. Показов 3997. Ответов 47
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Как правильно написать приведение к типу &(PVOID&) через reinterpret_cast?
(в Detours вообще написано что DetourAttach ждет первым аргументом void**, но когда я привожу к void** вместо &(PVOID&) то оно крашит процесс при внедрении :/
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.08.2021, 03:27
Ответы с готовыми решениями:

Ошибка: multiple definition of `void std::swap<A>(A&amp;, A&amp;)
Хочу специализировать swap для своего класса. Получаю ошибку. Вот код:#ifndef A_H #define A_H #include &lt;string&gt; class A ...

Язык C, напечатать таблицу истинности логической функции (A & B & C), где & - знаки логический операций И, НЕ
напечатать таблицу истинности логической функции (A &amp; B &amp; C), где &amp; - знаки логический операций И, НЕ

Почему friend ostrem& operator <<(ostream& outs, const Rational&); - invalid function declaration?
Пытаюсь скомпилировать программу пишет friend ostrem&amp; operator &lt;&lt;(ostream&amp; outs, const Rational&amp;); - invalid function declaration. ...

47
Заблокирован
21.08.2021, 19:45
Студворк — интернет-сервис помощи студентам
два вызова
C++
1
test(&(reinterpret_cast<PVOID>(TrueSleep)));
и
C++
1
2
PVOID lpvoid= reinterpret_cast<PVOID>(TrueSleep);  // так же как и ты выше в своем коде,
test(&lpvoid); // уже все ок
идентичны ? но первый не работает.

так что не убежден
Цитата Сообщение от DrOffset Посмотреть сообщение
Нет, все именно так. Никто тут ничего не продлевает.
завтра со свжей головой буду разбираться, где собака.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
21.08.2021, 19:51
Цитата Сообщение от SmallEvil Посмотреть сообщение
идентичны ?
С чего бы?
В первом у нас rvalue в результате каста.
А во втором у нас выражение lpvoid - это lvalue.

Добавлено через 3 минуты
Цитата Сообщение от SmallEvil Посмотреть сообщение
так что не убежден
Ссылка что-то может продлить только до конца блока, либо до конца полного выражения.
Так что вам достаточно немного подумать, что даже если бы это произошло, то "продленный" объект просто помер бы в конце выражения и DetourAttach получил бы адрес дохлого объекта. Но этого не происходит.
Так что ни о каком продлении речь тут не идет. Речь только о реинтерпретации.
0
Заблокирован
21.08.2021, 20:02
Цитата Сообщение от DrOffset Посмотреть сообщение
В первом у нас rvalue в результате каста.
Так о чем я и говорю, указателя на указатель достаточно для изменения исходного указателя.
вот поэтому в реинтерперт каст в вызове функции и добавлена ссылка (ссылка на указатель), то есть из ссылки можно взять адресс, а из rvalue нет.

ладно, походу я совсем запутался, или меня запутали.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
21.08.2021, 20:09
SmallEvil, да, и работа с "продленным" временным объектом (я пишу это не потому, что допускаю тут хоть малейшую возможность наличия тут этого явления, а для того, чтобы на ваших ошибочных рассуждениях вам было проще увидеть их ошибочность) противоречит тому, что задумано в этом коде. Нужно изменить именно TrueSleep.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
 
void Sleep(unsigned) {
    std::cout << "Original sleep\n";
}
 
static void (* TrueSleep)(unsigned) = Sleep;
 
static void AnotherSleep(unsigned) {
    std::cout << "Another sleep\n";
}
 
void test(void ** p)
{
    *p = reinterpret_cast<void*>(&AnotherSleep);
}
 
int main()
{
    TrueSleep(0);
    {
        test(&reinterpret_cast<void*&>(TrueSleep));
    }
    TrueSleep(0);    
}
https://rextester.com/AVCFI76003

А вариант с продлением, если бы он тут был возможен, работал бы так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
 
void Sleep(unsigned) {
    std::cout << "Original sleep\n";
}
 
static void (* TrueSleep)(unsigned) = Sleep;
 
static void AnotherSleep(unsigned) {
    std::cout << "Another sleep\n";
}
 
void test(void ** p)
{
    *p = reinterpret_cast<void*>(&AnotherSleep);
}
 
int main()
{
    TrueSleep(0);
    {
        void * tmpExtended = reinterpret_cast<void*>(TrueSleep);
        test(&tmpExtended);
    }
    TrueSleep(0);    
}
https://rextester.com/QQO44259

Добавлено через 47 секунд
Цитата Сообщение от SmallEvil Посмотреть сообщение
Так о чем я и говорю, указателя на указатель достаточно для изменения исходного указателя.
Нет, не достаточно.
Короче, см. выше примеры.
После него все должно быть понятно.

Добавлено через 39 секунд
Цитата Сообщение от SmallEvil Посмотреть сообщение
вот поэтому в реинтерперт каст в вызове функции и добавлена ссылка (ссылка на указатель), то есть из ссылки можно взять адресс, а из rvalue нет.
Это верно.
Но не потому что там что-то продлевается.
0
Заблокирован
21.08.2021, 20:23
Цитата Сообщение от DrOffset Посмотреть сообщение
Но не потому что там что-то продлевается.
да, не потому, а потому что после каста из ссылкой, выходит другой тип чем каст из PVOID, вот в этом мне и стоит разобраться (поэксперементировать). Спасибо за терпимость и понимание.

То есть, каст со ссылкой не является rvaluе.
Только вчера начал читать Мейерса и первая глава там об этом .

Добавлено через 37 секунд
Цитата Сообщение от DrOffset Посмотреть сообщение
Нет, не достаточно.
достаточно
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
21.08.2021, 20:27
Цитата Сообщение от SmallEvil Посмотреть сообщение
достаточно
Я имел в виду,что вот такого
Цитата Сообщение от eXpl01TeR Посмотреть сообщение
привожу к void** вместо &(PVOID&) то оно крашит процесс при внедрении :/
недостаточно.
0
Заблокирован
21.08.2021, 20:34
вот не ожидал что с реинтерперт каст будут камни подводные ...
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
21.08.2021, 20:49
Цитата Сообщение от SmallEvil Посмотреть сообщение
а потому что после каста из ссылкой, выходит другой тип чем каст из PVOID
Так я об этом и говорил.
Цитата Сообщение от DrOffset Посмотреть сообщение
Ссылка тут дает возможно работать непосредственно с объектом TrueSleep (а не с временным объектом) в результате каста.
Каст интерпретировал тип TrueSleep другим образом, но ссылка дала возможно применить эту интерпретацию непосредственно к объекту TrueSleep (т.е. сослаться на него, но под видом другого типа).

Не понятно тогда чего вы решили, что
Цитата Сообщение от SmallEvil Посмотреть сообщение
кажется тут немного не так
Если же мы просто скастим TrueSleep к void**, как это сделал ТС, то мы не добьемся такого же эффекта. Мы просто получим значение исходного указателя на функцию в качестве указателя на указатель. В то время как нам нужно получить адрес исходного указателя на функцию.

Добавлено через 10 минут
Цитата Сообщение от SmallEvil Посмотреть сообщение
вот не ожидал что с реинтерперт каст будут камни подводные ...
Тут вроде бы все на поверхности. Просто не нужно заниматься делами без понимания того что за ними стоит.

Мы, грубо говоря, открываем электрический щиток и начинаем тыкать без разбора во все цепи отверткой (электрик внеше же так же делал), а когда получаем короткое замыкание - чешем репу и говорим "вот уж не ожидал, что со щитком такие подводные камни". Это звучит очень глупо, когда экстраполируется на реальную жизнь, а в программировании запросто может быть
Цитата Сообщение от eXpl01TeR Посмотреть сообщение
Я её сам не понимаю, но везде в примерах перехвата через Microsoft Detours пишут именно через &(PVOID&)
Добавлено через 4 минуты
Кстати, всегда своим новым сотрудникам говорю, что примеры в документации даются не для переписывания в ваш код, а для того чтобы вы разобрались в принципах работы.
0
Заблокирован
21.08.2021, 21:02
Пример со щитком так себе, как и любые другие аналогии, которые я не люблю, в щитке все ясно, и все выглядит тем чем есть, не так как с++...
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
21.08.2021, 21:02
SmallEvil, для кого-то в щите выглядит "чем есть", а для условного ребенка не выглядит. Он запросто может так сделать. А для меня вся эта ситуация выглядит "чем есть". А для кого-то - это "магия", так же как для ребенка "магия" то, что делает электрик. Т.е. тут разница всего лишь в уровне предметной области. В электрощит вникнуть проще, чем в то, что делается в программировании, но по сути само "вникание" - это действие одной природы.

И на самом деле это не аналогия. Это демонстрация общего подхода, который можно описать коротко как "начать фигачить без понимания сути дела". Сама по себе деятельность не играет роли.
0
21.08.2021, 21:08

Не по теме:

Цитата Сообщение от SmallEvil Посмотреть сообщение
так себе, как и любые другие аналогии
Чувак, он не работу программиста с работой электрика сравнивает, а объясняет тупое обезъяничание в любой работе.
Нет тут никакой аналогии, речь все время об одном.

0
Заблокирован
21.08.2021, 21:09
Цитата Сообщение от DrOffset Посмотреть сообщение
"начать фигачить без понимания сути дела"
ну это не про меня (хотя по последним постам могло быть адресовано мне), и еще код по тому что достаточно указателя на указетель.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
void changePointer(void ** pp){
    int * pi = new int;
    *pi=111;
     *pp = reinterpret_cast<int *>(pi);
}
int main()
{
    int i = 101;
    int * pi = &i; // указтель на inr
    //changePointer(&reinterpret_cast<void*>(pi)); //  error: lvalue required as unary ‘&’ operand
                                                 //changePointer(&reinterpret_cast<void*>(pi));
    void * ppi =&pi;
    changePointer((void**)(&pi));
    std::cout<<*pi<<std::endl;
}
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
21.08.2021, 21:14
SmallEvil, этот код о том, что достаточно просто указателя, у которого возможно взять правильный адрес.
Такой же пример я выше показывал в #10

А слова о том, что достаточно void** я понял в контексте того, что описывал ТС в первом сообщении.
1
Заблокирован
21.08.2021, 21:18
но фишку с рентерпетркаст надо записывать отдельно , в большой блокнот
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
21.08.2021, 21:24
Цитата Сообщение от SmallEvil Посмотреть сообщение
еще код по тому что достаточно указателя на указетель.
Резюмируем, что ТС проще всего сделать так:
C++
1
reinterpret_cast<PVOID*>(&TrueSleep);
Сначала получим адрес указателя на функцию, а потом интерпретируем его как PVOID*, это наиболее простой для понимания способ.
А вот зачем в примерах MS они делали не так (PVOID*)(&TrueSleep), а так &(PVOID&)(TrueSleep) - непонятно. Никакой практической ценности именно в таком подходе здесь нет.
Эта ситуация еще раз красноречиво намекает на то, что переписывать примеры к себе в код - не надо.
1
Заблокирован
21.08.2021, 21:31
Цитата Сообщение от DrOffset Посмотреть сообщение
reinterpret_cast<PVOID*>(&TrueSleep);
мне уже сложно искать правильный ответ, его нужно искать сначала,
но такое не пройдет !

Добавлено через 1 минуту
ибо, шаблонная функция - реинтерпреткаст с простым указателем даст рвалую

Добавлено через 26 секунд
а с ссылкой даст ссылку
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
21.08.2021, 21:39
Цитата Сообщение от SmallEvil Посмотреть сообщение
но такое не пройдет !
Все пройдет.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <windows.h>
#include <detours.h>
 
static LONG dwSlept = 0;
 
// Target pointer for the uninstrumented Sleep API.
//
static VOID (WINAPI * TrueSleep)(DWORD dwMilliseconds) = Sleep;
 
// Detour function that replaces the Sleep API.
//
VOID WINAPI TimedSleep(DWORD dwMilliseconds)
{
    // Save the before and after times around calling the Sleep API.
    DWORD dwBeg = GetTickCount();
    TrueSleep(dwMilliseconds);
    DWORD dwEnd = GetTickCount();
 
    InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
}
 
// DllMain function attaches and detaches the TimedSleep detour to the
// Sleep target function.  The Sleep target function is referred to
// through the TrueSleep target pointer.
//
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
    if (DetourIsHelperProcess()) {
        return TRUE;
    }
 
    if (dwReason == DLL_PROCESS_ATTACH) {
        DetourRestoreAfterWith();
 
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(reinterpret_cast<PVOID*>(&TrueSleep), TimedSleep);
        DetourTransactionCommit();
    } else if (dwReason == DLL_PROCESS_DETACH) {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(reinterpret_cast<PVOID*>(&TrueSleep), TimedSleep);
        DetourTransactionCommit();
    }
    return TRUE;
}
Цитата Сообщение от SmallEvil Посмотреть сообщение
ибо, шаблонная функция - реинтерпреткаст с простым указателем даст рвалую
При чем тут шаблон?
В любом случае это не помешает.

Добавлено через 2 минуты
....
Цитата Сообщение от SmallEvil Посмотреть сообщение
но такое не пройдет !
Цитата Сообщение от SmallEvil Посмотреть сообщение
C++
1
changePointer((void**)(&pi));
Удивительно как вы умудрились противоречить сами себе.
Вы только что предложили самое лучшее для ТС решение его вопроса, и даже продемонстрировали его кодом, но стоило мне вас поддержать, так вы сразу же бросились со мной спорить. Это как так?
0
155 / 9 / 2
Регистрация: 14.08.2019
Сообщений: 771
21.08.2021, 21:41  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Резюмируем, что ТС проще всего сделать так:
C++
1
reinterpret_cast<PVOID*>(&TrueSleep);
Забавно, вчера я именно так и сделал, но подумал что это как-то слишком просто и что я явно где-то ошибся)

Так лучше делать
C++
1
DetourAttach(&reinterpret_cast<PVOID&>(pFunc), myFunc);
или
C++
1
DetourAttach(reinterpret_cast<PVOID*>(&pFunc), myFunc);
В чем отличие?
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
21.08.2021, 21:43
Цитата Сообщение от eXpl01TeR Посмотреть сообщение
В чем отличие?
Все отличия описаны выше. Я второй раз так распинаться не буду

Добавлено через 45 секунд
Цитата Сообщение от eXpl01TeR Посмотреть сообщение
Так лучше делать
Второй вариант понятнее, на мой взгляд. Требует меньше знаний для использования.
1
Заблокирован
21.08.2021, 21:47
Цитата Сообщение от DrOffset Посмотреть сообщение
Это как так?
нет это не так, я просто реально заблудился ) сорри
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.08.2021, 21:47
Помогаю со студенческими работами здесь

В заштрихованную фигуру бросают точки с координатами x и y. Получить координаты первой точки не попавшей в эту область (фигура x*x+y*y<25&&x*x+y*y>=9&
В заштрихованную фигуру бросают точки с координатами x и y. Получить координаты первой точки не попавшей в эту область (фигура...

ostream &operator<< (ostream &output, const Array &obj) - что означает эта строка?
void Array::getArray() // вывод массива { for (int ix = 0; ix &lt; size; ix++) cout &lt;&lt; setw(5) &lt;&lt; ptr; // вывод элементов...

Нюансы синтаксиса: где, как и для чего используется &&
Когда применяется ссылка на ссылку? В STL есть классы, конструкторы которых принимают ссылку на ссылку. Попробовал понять для чего они...

Как проверить, принадлежит ли символ заданному диапазону m...n, кроме if (c <= n && c >= m) ?
есть какая-нибудь более короткая запись для проверки, принадлежит ли символ заданному диапазону m...n, кроме if (c &lt;= n &amp;&amp; c...

Порядок вычисления: операторы «|» и «||», «&» и «&&»
В Java булевые операторы «|» и «||», и «&amp;» и «&amp;&amp;» отличаются друг от друга порядком вычеслений, а в C++ так же как и в Java или...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru