Форум программистов, компьютерный форум, киберфорум
C++: COM, OLE, ActiveX
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
89 / 87 / 33
Регистрация: 20.07.2016
Сообщений: 372
1

Петцольд OLE IMalloc

10.11.2019, 00:14. Просмотров 1847. Ответов 2
Метки нет (Все метки)

Пример из книги падает во время выполнения, компилятор пишет ересь. Падения происходит при попытке достучаться к любой услуге интерфейсов IUnknown или IMalloc.
О том что компилятор болеет - четко видно на приложенном скрине. pDAlloc не может быть nullptr, если б не удалось выделать память new бросил бы std::bad_alloc.

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
#ifndef IMALLOC_H
 
#define IMALLOC_H
 
#include <windows.h>
 
//======================================================================
#define EXPORT extern "C" __declspec(dllexport)
 
EXPORT LPMALLOC CreateAllocator ();
 
#undef INTERFACE
#define INTERFACE DAlloc
 
//======================================================================
DECLARE_INTERFACE_(DAlloc, IMalloc)
{
  // IUnknown
  STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppv);
  STDMETHOD_(ULONG, AddRef)(THIS);
  STDMETHOD_(ULONG, Release)(THIS);
 
  // IMalloc
  STDMETHOD_(void*, Alloc)(THIS_ ULONG cb);
  STDMETHOD_(void*, Realloc)(THIS_ void* pv, ULONG cb);
  STDMETHOD_(void, Free)(THIS_ void* pv);
  STDMETHOD_(ULONG, GetSize)(THIS_ void* pv);
  STDMETHOD_(int, DidAlloc)(THIS_ void* pv);
  STDMETHOD_(void, HeapMinimize)(THIS);
 
#ifndef CINTERFACE
  private:
    ULONG m_uiRefCnt = 0;
    HANDLE m_handle = nullptr;
 
  public:
    DAlloc () = default;
 
    bool Initialize ();
 
    ~DAlloc ();
#endif
};
 
//======================================================================
#endif
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "IMalloc.h"
 
//======================================================================
EXPORT LPMALLOC CreateAllocator ()
{
  auto pDAlloc = new DAlloc();
  if (pDAlloc->Initialize())
    pDAlloc->AddRef();
  else
  {
    delete pDAlloc;
    pDAlloc = nullptr;
  }
  return reinterpret_cast<LPMALLOC>(pDAlloc);
}
 
//======================================================================
STDMETHODIMP DAlloc::QueryInterface (REFIID riid, LPVOID FAR* ppv)
{
  *ppv = nullptr;
 
  if (riid == IID_IUnknown)
    *ppv = reinterpret_cast<IUnknown*>(this);
  else if (riid == IID_IMalloc)
    *ppv = reinterpret_cast<IMalloc*>(this);
 
  if (*ppv)
  {
    AddRef();
    return S_OK;
  }
  return E_NOINTERFACE;
}
 
//======================================================================
STDMETHODIMP_(ULONG) DAlloc::AddRef ()
{ return ++m_uiRefCnt; }
 
//======================================================================
STDMETHODIMP_(ULONG) DAlloc::Release ()
{
  if (!--m_uiRefCnt)
  {
    delete this;
    return 0;
  }
  return m_uiRefCnt;
}
 
//======================================================================
STDMETHODIMP_(void*) DAlloc::Alloc (ULONG cb)
{ return HeapAlloc(m_handle, HEAP_ZERO_MEMORY, cb); }
 
//======================================================================
STDMETHODIMP_(void*) DAlloc::Realloc (void* pv, ULONG cb)
{ return HeapReAlloc(m_handle, HEAP_ZERO_MEMORY, pv, cb); }
 
//======================================================================
STDMETHODIMP_(void) DAlloc::Free (void* pv)
{ HeapFree(m_handle, 0, pv); }
 
//======================================================================
STDMETHODIMP_(ULONG) DAlloc::GetSize (void* pv)
{ return HeapSize(m_handle, 0, pv); }
 
//======================================================================
STDMETHODIMP_(int) DAlloc::DidAlloc (void* pv)
{
  PROCESS_HEAP_ENTRY phe;
  ZeroMemory(&phe, sizeof(phe));
 
  while (HeapWalk(m_handle, &phe))
    if (phe.lpData == pv)
      return true;
  return false;
}
 
//======================================================================
STDMETHODIMP_(void) DAlloc::HeapMinimize ()
{ HeapCompact(m_handle, 0); }
 
//======================================================================
bool DAlloc::Initialize ()
{
  m_handle = HeapCreate(0, 4096, 65535);
  return m_handle;
}
 
//======================================================================
DAlloc::~DAlloc ()
{
  if (m_handle)
    HeapDestroy(m_handle);
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "IMalloc.h"
 
//==================================================================================
int WINAPI WinMain (_In_     HINSTANCE,
                    _In_opt_ HINSTANCE,
                    _In_     LPSTR,
                    _In_     int)
{
  auto pMalloc = CreateAllocator();
 
  return 0;
}
0
Миниатюры
Петцольд OLE IMalloc  
Вложения
Тип файла: rar OLE.rar (1.2 Кб, 1 просмотров)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.11.2019, 00:14
Ответы с готовыми решениями:

Помогите с IMalloc
В Visual Studio 2008 следующий код не работает: IMalloc *pMalloc; SHGetMalloc(&amp;pMalloc);...

Петцольд, первый пример из книги
Доброго времени суток. Только начал изучать WinApi, и уже возникли вопросы: как компилировать make...

Книга для новичка. Чарльз Петцольд или Адам Натан?
Чарльз Петцольд или Адам Натан? Для новичка. Добавлено через 11 минут Узнал про эти книги из...

Как увидеть содержание типа OLE Object с помощью Delphi-Ole Conteiner?
Привет всем, я из Болгарии у меня такой вопрос: я работю с MSAccess и в ней есть Table и Field с...

2
89 / 87 / 33
Регистрация: 20.07.2016
Сообщений: 372
10.11.2019, 00:42  [ТС] 2
В общем код:
C++
1
DECLARE_INTERFACE_(DAlloc, IMalloc)
разворачивается в
C++
1
struct declspec(novtable) DAlloc: public IMalloc
что вроде как хорошо для абстрактных базовых классов, но приводит в негодность классы объекты которых можно создавать...
Дядя Петцольд, ты не хороший человек
1
Миниатюры
Петцольд OLE IMalloc  
5859 / 3987 / 1636
Регистрация: 07.05.2019
Сообщений: 12,391
Записей в блоге: 1
10.11.2019, 10:43 3
Цитата Сообщение от JIawliet Посмотреть сообщение
что вроде как хорошо для абстрактных базовых классов, но приводит в негодность классы объекты которых можно создавать...
Дядя Петцольд, ты не хороший человек
Просто уточню, что проблема в declspec(novtable)
Ну и добавлю, что reinterpret_cast здесь лучше не использовать, нужно использовать static_cast.
Во-первых, здесь в нём вообще нет смысла - к указателю на void и без него приведётся.
Во-вторых, можешь огрести проблемы - при множественном наследовании, преобразования к указателя на предка могут давать разные результаты. static_cast это учитывает, reinterpret_cast - нет.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.11.2019, 10:43

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Можно ли связанный (или внедренный) OLE объект прокрутить на форме в OLE контейнере?
Динамически связанный OLE объект (документ Word) не помещяется целиком в форме. Можно ли связанный...

Ошибка в ADO: Multi-step OLE-DB generated error. Check all OLE-DB status value, if available.No work was done'
Выполняю хранимую прогу cmd.Execute и получаю ошибку: 'Multi-step OLE-DB generated error. Check...

Произошли ошибки во время выполнения многошаговой операции OLE DB. По возможности, проверьте значения всех состояний OLE DB. Работа не выполнена
OleDbConnection cn = new OleDbConnection(&quot;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=&quot; +...

Создание OLE-сервера и OLE-документа
Господа Программисты!!! Просветите несведущего, пожалуйста. Нужно создать OLE-сервер, да такой,...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.