"Умный указатель" ну или какая-нибудь хрень в этом духе.

Тема в разделе "LANGS.C", создана пользователем _Juicy, 1 авг 2011.

  1. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    При работе с относительными смещениями (допустим, RVA) постоянно приходится прибавлять к ним одно и то же число.
    Можно ли/и как создать некую структуру в с/срр, чтобы *Pointer автоматически выдавало правильный адрес, к которому это число уже прибавлено?
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Можно.
     
  3. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    "Мы в России, Ватсон."
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Конечно в России. Вопрос немного странен. Чем не устраивает функция получения VA по RVA? Если так хотите то можно и вумный сделать, основы крестов - переопределение операторов.
     
  5. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    У меня макрос... не знаю, слишком много его, раздражает и засоряет код.

    Вот если вам, товарищ Бустер, не сложно, краткую выдержку из основ уровня детского сада...

    У меня так (для примера)
    Код (Text):
    1. typedef struct _IMPORT_DIRECTORY_ENTRY
    2. {
    3.     DWORD ImportLookUp;
    4.     DWORD TimeDateStamp;
    5.     DWORD ForwardChain;
    6.     DWORD NameRVA;
    7.     DWORD AddresTableRVA;
    8. }
    9. IMPORT_DIRECTORY_ENTRY;
    10. ...
    11. char* pName = RVA_TO_VA (pImportDirectoryEntry->NameRVA);
    12. lstrcmpi (pName, szTestName);
    Хотелось бы как-то так:
    Код (Text):
    1. typedef struct _IMPORT_DIRECTORY_ENTRY
    2. {
    3.     DWORD ImportLookUp;
    4.     DWORD TimeDateStamp;
    5.     DWORD ForwardChain;
    6.     ВУМНЫЙ_ПОЙНТЕР (char) NameRVA;
    7.     DWORD AddresTableRVA;
    8. }
    9. IMPORT_DIRECTORY_ENTRY;
    10. ...
    11. lstrcmpi (pImportDirectoryEntry->NameRVA, szTestName);
     
  6. srm

    srm New Member

    Публикаций:
    0
    Регистрация:
    14 июн 2011
    Сообщения:
    189
    Squash сделать то, конечно, можно. А откуда у Вас в макросе RVA_TO_VA берётся база?
     
  7. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Это неважно :)
     
  8. srm

    srm New Member

    Публикаций:
    0
    Регистрация:
    14 июн 2011
    Сообщения:
    189
    Squash это важно. Как класс rva_ptr будет вычислять va, не зная base? Или он будет инициализироваться этим самым base?
     
  9. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Как угодно, хоть из глобальной переменной.
    Или статической класса, например.
     
  10. srm

    srm New Member

    Публикаций:
    0
    Регистрация:
    14 июн 2011
    Сообщения:
    189
    Squash, вы не думаете, что от этого будет зависеть реализация и формат вызова? Вы хотите услышать ответ на свой вопрос: "можно ли так сделать или нет?" или же хотите получить конкретное решение?
     
  11. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Мне бы для начала посмотреть хоть на одну реализацию, с любым способом получения базы, какой вам больше нравится.
    Если вам не сложно.
     
  12. srm

    srm New Member

    Публикаций:
    0
    Регистрация:
    14 июн 2011
    Сообщения:
    189
    Вот так вот. Фигово, конечно.
    Код (Text):
    1. void* base;
    2.  
    3. template <typename T>
    4. class rva_offset
    5. {
    6. private:
    7.     size_t m_offset;
    8.  
    9. public:
    10.     rva_offset() :
    11.         m_offset(0)
    12.     {
    13.     }
    14.  
    15.     rva_offset(size_t offset) :
    16.         m_offset(offset)
    17.     {
    18.     }
    19.  
    20.     rva_offset(rva_offset const& a) :
    21.         m_offset(a.m_offset)
    22.     {
    23.     }
    24.  
    25.     T const* operator () ()
    26.     {
    27.         return reinterpret_cast<T const*>(static_cast<char const*>(base) + m_offset);
    28.     }
    29. };
    30.  
    31. typedef struct _XX_IMAGE_DOS_HEADER {      
    32.     WORD   e_magic;                    
    33.     WORD   e_cblp;                      
    34.     WORD   e_cp;                        
    35.     WORD   e_crlc;                      
    36.     WORD   e_cparhdr;                  
    37.     WORD   e_minalloc;                  
    38.     WORD   e_maxalloc;                  
    39.     WORD   e_ss;                        
    40.     WORD   e_sp;                        
    41.     WORD   e_csum;                      
    42.     WORD   e_ip;                        
    43.     WORD   e_cs;                        
    44.     WORD   e_lfarlc;                    
    45.     WORD   e_ovno;                      
    46.     WORD   e_res[4];                    
    47.     WORD   e_oemid;                    
    48.     WORD   e_oeminfo;                  
    49.     WORD   e_res2[10];                  
    50.     rva_offset<IMAGE_NT_HEADERS>   e_lfanew;
    51.   } XX_IMAGE_DOS_HEADER, *PXX_IMAGE_DOS_HEADER;
    52.  
    53. int main()
    54. {
    55.     XX_IMAGE_DOS_HEADER* dos = reinterpret_cast<XX_IMAGE_DOS_HEADER*>(GetModuleHandle(0));
    56.     base = GetModuleHandle(0);
    57.     IMAGE_NT_HEADERS const* nt = dos->e_lfanew();
    58. }
     
  13. srm

    srm New Member

    Публикаций:
    0
    Регистрация:
    14 июн 2011
    Сообщения:
    189
    честно говоря, толку здесь от smart pointer'a я не вижу. Тут либо придётся делать reinterpret_cast с оффсетов стандартных структур IMAGE_DOS_HEADER, IMAGE_NT_HEADERS и т.д. или все эти структуры самостоятельно переопределять. И то и другое - гемор. Лучше уж функцию сделать инлайновую.. Как-то так...

    Код (Text):
    1. template <typename t>
    2. t* rva_to_va(void* base, size_t offset)
    3. {
    4.  return reinterpret_cast<t*>(static_cast<char*>(base) + offset);
    5. }
     
  14. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Сцуко, тяжело :)
    Ну ничего, попробую разобраться. Спасибо.
     
  15. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Сдаётся мне что автор употребил термин "Умный указатель" не подозревая о том что он уже занят, так что не стоит по этому поводу заморачиваться.
     
  16. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Автору встречалось это название при работе с IUnknown-интерфейсами, и вроде бы эта штука самостоятельно делает AddRef при инициализации и Release при уничтожении, но в том, как это работает, я очень слабо разбираюсь.
     
  17. srm

    srm New Member

    Публикаций:
    0
    Регистрация:
    14 июн 2011
    Сообщения:
    189
    Squash используйте обычные функции, как написано в #14.
     
  18. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    Да переименуй ты макрос во что-нибудь покороче, например так:
    Код (Text):
    1. #define _ RVA_TO_VA
    Ну или, на любителя решение: на каждое поле добавь две функции акцессоры: get_value, set_value. Только имена им подбери покороче. ;)
     
  19. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    насчет умных указателей для разбора РЕ в виде С++ гугль посоветовал глянуть сюда

    http://www.pelib.com

    но вообщето литературы включая книги, включая на ру хватает. но я так понял, что ТС не охота заморачиваться. есть готовые решения для разбора. и на С, и на С++, и даже на питоне
     
  20. ant_man

    ant_man New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2004
    Сообщения:
    23
    Код (Text):
    1. DWORD BASE=0x2;
    2.  
    3. class RVA
    4. {
    5. public:
    6.     DWORD rva;
    7.     template<typename T>
    8.     operator T ()
    9.     {
    10.         return (T)(BASE + rva);
    11.     };
    12. };
    13.  
    14. void main()
    15. {
    16.     PVOID r=(PVOID)"ABCDE\n";
    17.  
    18.     printf((RVA &)r);
    19. }
    CDE