Как правильно получить по адресу
От: indee  
Дата: 10.12.20 12:19
Оценка: -1
Нужно получит экземпляра объекта по его адресу:

MyObj* myObj = NULL;

long CreateObj(){
    myObj = new MyObj();
    return (long)myObj;
}
...
void getObj(long p){
  MyObj* pObj = (MyObj*)p;     
}


Правильно ли это, как это можно улучшить/обезопасить и правильно обвернуть MyObj* pObj = (MyObj*)p в try-catch?

Спасибо!
Отредактировано 10.12.2020 12:20 indee . Предыдущая версия .
Re: Как правильно получить по адресу
От: TailWind  
Дата: 10.12.20 12:22
Оценка:
Указатель на виртуальный базовый класс возвращай, а не long
Re: Как правильно получить по адресу
От: Bill Baklushi СССР  
Дата: 10.12.20 12:28
Оценка: +1 :)))
indee:

I>Правильно ли это, как это можно улучшить/обезопасить и правильно обвернуть


Ты не родственник GhostCoder-а? Тот торговал обвёртками.
Re[2]: Как правильно получить по адресу
От: indee  
Дата: 10.12.20 12:30
Оценка:
Здравствуйте, TailWind, Вы писали:

TW>Указатель на виртуальный базовый класс возвращай, а не long

Не могу, т.к. мне известено только long значение.
Re: Как правильно получить по адресу
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.12.20 12:32
Оценка: +2
Здравствуйте, indee, Вы писали:

I>Нужно получит экземпляра объекта по его адресу:


Платформа какая?
Если 64-битная винда, то указатель — 64 бита, а long — 32 (не спрашивай почему они такие извращенцы, когда даже в дотнете long — 64).
Тебе нужен uintptr_t, а не long.

Но в общем случае такие пляски нужны только в особых случаях, типа передачи через WinAPI. А зачем в обычном коде приводить указатель к целому?

I>Правильно ли это, как это можно улучшить/обезопасить и правильно обвернуть MyObj* pObj = (MyObj*)p в try-catch?


Тут оборачивать не надо, если исходное значение было правильным указателем. А вот если нет причины ему доверять — то нельзя доверять и указателю без проверки.

А так уже сказали — указатель на объект базового класса решает >=90% подобных проблем.
The God is real, unless declared integer.
Re: Как правильно получить по адресу
От: Bill Baklushi СССР  
Дата: 10.12.20 12:34
Оценка:
indee:

I>Правильно ли это, как это можно улучшить/обезопасить и правильно обвернуть MyObj* pObj = (MyObj*)p в try-catch?

За преобразование целого в указатели без крайней нужды — выгоняют босиком на мороз.

Почему бы не возвращать сам указатель?:
MyObj *CreateObj()


Если уж невтерпёж кастовать между целым и указателем лучше использовать специальные совместимые по размеру типы вроде uintptr_t.
Re[2]: Как правильно получить по адресу
От: indee  
Дата: 10.12.20 12:37
Оценка: :)))
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, indee, Вы писали:


I>>Нужно получит экземпляра объекта по его адресу:


N>Платформа какая?

N>Если 64-битная винда, то указатель — 64 бита, а long — 32 (не спрашивай почему они такие извращенцы, когда даже в дотнете long — 64).
N>Тебе нужен uintptr_t, а не long.

N>Но в общем случае такие пляски нужны только в особых случаях, типа передачи через WinAPI. А зачем в обычном коде приводить указатель к целому?


I>>Правильно ли это, как это можно улучшить/обезопасить и правильно обвернуть MyObj* pObj = (MyObj*)p в try-catch?


N>Тут оборачивать не надо, если исходное значение было правильным указателем. А вот если нет причины ему доверять — то нельзя доверять и указателю без проверки.


N>А так уже сказали — указатель на объект базового класса решает >=90% подобных проблем.


64-битная винда.
Адрес хранится в БД, поэтому указатель на объект базового класса использовать не могу.
Re[3]: Как правильно получить по адресу
От: kov_serg Россия  
Дата: 10.12.20 12:41
Оценка:
Здравствуйте, indee, Вы писали:

I>64-битная винда.

I>Адрес хранится в БД, поэтому указатель на объект базового класса использовать не могу.
Зачем так делать?
Re[4]: Как правильно получить по адресу
От: indee  
Дата: 10.12.20 12:44
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, indee, Вы писали:


I>>64-битная винда.

I>>Адрес хранится в БД, поэтому указатель на объект базового класса использовать не могу.
_>Зачем так делать?

Из потустороннего мира используются ресурсы Win API.
Re[3]: Как правильно получить по адресу
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.12.20 12:47
Оценка:
Здравствуйте, indee, Вы писали:

N>>Платформа какая?

N>>Если 64-битная винда, то указатель — 64 бита, а long — 32 (не спрашивай почему они такие извращенцы, когда даже в дотнете long — 64).
N>>Тебе нужен uintptr_t, а не long.

I>64-битная винда.


Ну таки uintptr_t, а если его нет — unsigned long long.

I>Адрес хранится в БД, поэтому указатель на объект базового класса использовать не могу.


Адрес в БД на объекты рантайма процесса... по-моему, супербред.
А что будет в случае рестарта процесса?
Может, ввести таблицу хэндлов и писать в БД именно их?
The God is real, unless declared integer.
Re: Как правильно получить по адресу
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 10.12.20 12:47
Оценка: +2
Здравствуйте, indee, Вы писали:

I>Нужно получит экземпляра объекта по его адресу:


Указатель можно с помощью reinterpret_cast скастовать к intptr_t. Так с адресами работать корректно.
Re: Как правильно получить по адресу
От: Coreman  
Дата: 10.12.20 12:54
Оценка:
Здравствуйте, indee, Вы писали:

* try-catch тут не поможет, если вдруг...
* Лучше возвращать не указатель в лонге, а скажем значение ключа из мапы. А по этому ключу из мапы потом доставать объект.
Re[3]: Как правильно получить по адресу
От: TailWind  
Дата: 10.12.20 13:02
Оценка:
TW>>Указатель на виртуальный базовый класс возвращай, а не long
I>Не могу, т.к. мне известено только long значение.

Ну добавь в объект, например, массив char a[10]
В конструкторе заполни уникальными байтами

После получения указателя проверь что байты по этому смещению равны константе
Если нет — exception

Хоть какая-то защита

А вообще у вас конечно ошибка проектирования
Re: Как правильно получить по адресу
От: B0FEE664  
Дата: 10.12.20 23:08
Оценка:
Здравствуйте, indee, Вы писали:

I>Нужно получит экземпляра объекта по его адресу:

I>
I>MyObj* myObj = NULL;

I>long CreateObj(){
I>    myObj = new MyObj();
I>    return (long)myObj;
I>}
I>...
I>void getObj(long p){
I>  MyObj* pObj = (MyObj*)p;     
I>}
I>

Я ничего не понял.
Почему не?:
MyObj* myObj = NULL;

long CreateObj(){
    myObj = new MyObj();
    return (long)myObj;
}
...
void getObj(long p){
  MyObj* pObj = myObj;     
}



Ну, я если экономите на спичках указателях, то так:
MyObj* myObjs[256];
std::uint8_t last = 0;

long CreateObj(){
    //assert(0xFF != last && "Open up the limit :)");
    myObjs[last++] = new MyObj();
    return last - 1;
}
...
void getObj(long p){
  //assert(0 <= p && p <= 255);
  MyObj* pObj = myObjs[p];
}


I>Правильно ли это,

нет.

I>как это можно улучшить/обезопасить

тысячи есть способов.

I> и правильно обвернуть MyObj* pObj = (MyObj*)p в try-catch?

нет. не правильно.
И каждый день — без права на ошибку...
Re[5]: Как правильно получить по адресу
От: AleksandrN Россия  
Дата: 11.12.20 09:11
Оценка:
Здравствуйте, indee, Вы писали:

I>Здравствуйте, kov_serg, Вы писали:


_>>Здравствуйте, indee, Вы писали:


I>>>64-битная винда.

I>>>Адрес хранится в БД, поэтому указатель на объект базового класса использовать не могу.
_>>Зачем так делать?

I>Из потустороннего мира используются ресурсы Win API.


Тип HANDLE в WinAPI это void*. Почему бы не использовать его?
А хранить адрес в БД зачем? Почему приложение само не хранит адрес? Что будет, если процесс остановится нештатно? Как БД вычищаться будет?
Re[6]: Как правильно получить по адресу
От: Carc Россия http://www.amlpages.com/home.php
Дата: 11.12.20 09:20
Оценка:
Здравствуйте, AleksandrN, Вы писали:


I>>Из потустороннего мира используются ресурсы Win API.


AN>Тип HANDLE в WinAPI это void*.

Ох, блин далеко как не всегда... Очень даже не всегда! Хендлы бывают разных типов, это раз…

А еще в разных версиях Windows хендлы одного и того же типа могут быть с-а-а-всем разные по начинке. Это два-с…

В одном случае это может и правда указатель вида void*, в соседней винде это может быть и вовсе некий индекс, или ключ в определенной внутренней таблице Windows.
Aml Pages Home
Отредактировано 11.12.2020 15:00 Carc . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.