Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.95/62: Рейтинг темы: голосов - 62, средняя оценка - 4.95
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633

OLE(Object Linking and Embedding)?

24.01.2024, 23:07. Показов 14688. Ответов 167

Студворк — интернет-сервис помощи студентам
Здравствуйте! Приступил к изучению темы OLE, если кто-то эту тему понимает, то ему не составит труда пояснить что это за зверь такой, ну, или пояснить некоторые моменты, мелочи. Вот одна такая "мелочь"
Почему автор объявляет класс так:
Кликните здесь для просмотра всего текста
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
#ifndef IMALLOC_H
#define IMALLOC_H
 
/*==================================================================
    IMALLOC.H
    C Interface to private allocator
======================================================================*/
#define EXPORT extern "C" __declspec(dllexport)
 
EXPORT LPMALLOC CreateAllocator();
 
//----------------------------------------------
//Implementation of allocator interface
//------------------------------------------------------------------------
#undef INTERFACE 
#define INTERFACE DAlloc 
 
DECLARE_INTERFACE_(DAlloc, IMalloc)
{
    // *** IUnknown methods ***
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppv);
    STDMETHOD_(ULONG, AddRef)(THIS);
    STDMETHOD_(ULONG, Release)(THIS);
 
    // *** IMalloc methods ***
    STDMETHOD_(void*, Alloc)(THIS_ ULONG cb);
    STDMETHOD_(void*, Realloc)(THIS_ void* pv, ULONG cb);
    STDMETHOD_(void, Free)(THIS_ void* pv);
    STDMETHOD_(size_t, GetSize)(THIS_ void* pv);
    STDMETHOD_(int, DidAlloc)(THIS_ void* pv);
    STDMETHOD_(void, HeapMinimize)(THIS);
 
#ifndef CINTERFACE 
public:
    DAlloc();
    ~DAlloc();
    BOOL Initialize();
 
private:
    ULONG RefCount;
    HANDLE hHeap;
#endif
 
};
 
 
#endif

Это что-то абсолютно мне не знакомое, и, если на win32 DLL-библиотека собирается, то для win64 уже нет, ругается
Code
1
2
3
4
5
imalloc.cpp(15): error C2259: "DAlloc": невозможно создать экземпляр абстрактного класса
imalloc.h(19): message : см. объявление "DAlloc"
imalloc.cpp(15): message : из-за следующих членов:
imalloc.cpp(15): message : void *IMalloc::Alloc(SIZE_T): абстрактный
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\objidlbase.h(1151): message : см. объявление "IMalloc::Alloc"
Но почему эти ошибки не касаются win32 библиотеки?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.01.2024, 23:07
Ответы с готовыми решениями:

Error linking glsl Program Object
Здравствуйте уважаемые гуру. Устроился на работу, дали проект, проект компилится, собирается но проблемма такая: на некоторых компьютерах...

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

Изменить Свойство Ole Object
Добрый день. Ткните носом кто-нибудь плз., как программно поменять свойство Display As вставленного в Rich Text поля OLE Object-а типа...

167
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
16.02.2024, 23:20  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Ygg Посмотреть сообщение
Да, это то же просто. Всего лишь несколько дополнительных приёмов наращивания функционала вокруг уже имеющейся реализации помимо стандартного в С++ наследования. Это очень специфичные приёмы, которые не играют существенной роли в архитектуре COM.
Просто! Отлично, значит не для всех это просто, бесконечное: "ах, это же так просто, банально...". Да, всего лишь несколько компонентов, но это я и сам понял, что это всего лишь какой-то приём для создания чего-то, если бы мне было всё очевидно, я бы вопросы не задавал.


Цитата Сообщение от Замабувараев Посмотреть сообщение
а заимствовали таблицу из класса.
Т.е. как это происходит... кто-то наследует от родителя, скажем IMalloc, и этого наследника уже появляется vtbl, так? А если код пишется на Си, тогда как?

Не по теме:

Цитата Сообщение от Замабувараев Посмотреть сообщение
Чтобы программы написанные на разных языках программирования могли взаимодействовать между собой.
Тоже самое пишут о С++, если дело качается средних и больших проектов, дак в чём разница?



Не по теме:

Цитата Сообщение от politoto Посмотреть сообщение
Это уже тема Microsoft Visual C++.
Ясно, что ничего не ясно.

0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
17.02.2024, 06:12
Цитата Сообщение от Liss29 Посмотреть сообщение
А если код пишется на Си, тогда как?
На си++ за вас это делает компилятор, а в си нужно руками добавлять в структуру указатель на массив указателей на функции.
Цитата Сообщение от Liss29 Посмотреть сообщение
Тоже самое пишут о С++, если дело качается средних и больших проектов, дак в чём разница?
Нет конечно. Мало того, что вам не гарантируют совместимость между си++ библиотеками от разных компиляторов, так ещё никто не гарантирует переносимость между разными версиями стандарта си++. Конструкции, которые законны в одном си++ стандарте, могут быть незаконны в другом си++ стандарте, и компилироваться не будут.

Поэтому и придумали COM, чтобы можно было использовать программы написанные в другом языке.
0
17.02.2024, 08:58

Не по теме:

Цитата Сообщение от Замабувараев Посмотреть сообщение
Можно было бы взять 64‐битное число, но его уникальность не гарантируется, а для 128‐битного числа вероятность совпадения очень мала.
Если бы это было число, то почему бы не использовать какой-нибудь __int128 ?
И зачем бы нужна была вселенская (глобальная в случае COM) уникальность, если и по строке работает активация кода из другой программы, написанной на неважно каком языке?
Windows Batch file
1
start pb.vbs & tasklist /FI "IMAGENAME eq mspaint.exe" & type pb.vbs
Имя образа PID Имя сессии № сеанса Память
========================= ======== ================ =========== ============
mspaint.exe 7668 Console 7 7 672 КБ
Visual Basic
1
2
set paint = CreateObject ("pbrush")
msgbox typename(paint)

0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
17.02.2024, 09:21
Цитата Сообщение от politoto Посмотреть сообщение
Если бы это было число, то почему бы не использовать какой-нибудь __int128 ?
Это делается потому, что в Win16 и Win95 не было никаких __int128.
Поэтому GUID объявлен в виде структуры. Тем не менее, мы никогда не работаем с GUID как со структурой, мы воспринимаем его как единое число.
Цитата Сообщение от politoto Посмотреть сообщение
И зачем бы нужна была вселенская (глобальная в случае COM) уникальность, если и по строке работает активация кода из другой программы
Чтобы не было конфликтов когда кто‐нибудь решит назвать класс MyClass или ITestInterface.
Цитата Сообщение от politoto Посмотреть сообщение
CreateObject ("pbrush")
Какой объект создастся? Ваш или чужой?
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
17.02.2024, 23:35  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
а в си нужно руками добавлять в структуру указатель на массив указателей на функции.
Знаю я, что в С++ это делает компилятор, значить в Си это делает человек, создаётся указатель на функцию далее этот указатель помещается в массив указателей на функции, вот тебе и таблица виртуальных функций. А что столь интеллектуальная библиотека COM не создаёт внутри себя подобного?! создаёт, но почему это не пашет в коде, который привел в качестве примера Петзольд...
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
//Задание типов указателей на функции 
typedef void* (*PFNALLOC)(ULONG);
typedef void* (*PFNREALLOC)(void*, ULONG);
typedef void* (*PFNFREE)(void*);
typedef void* (*PFNGERSIZE)(void*);
typedef void* (*PFNDIDALLOC)(void*);
typedef void* (*PFNHEAPMINIMIZE)(void);
 
//Определение структуры с указателями на функции.
typedef struct tagALLOCATOR
{
    PFNALLOC          Alloc;
    PFNREALLOC        Realloc;
    PFNFREE           Free;
    PFNGETSIZE        GetSize;
    PFNDIDALLOC       DidAlloc;
    PFNHEAPMINIMIZE   HeapMinimize;
} ALLOCATOR;
 
ALLOCATOR imalloc = { Alloc, Realloc, Free, GetSize, DidAlloc, 
                      HeapMinimize };
                      
ALLOCATOR* FetchAllocator()
{
    return &imalloc;
}

Цитата Сообщение от Замабувараев Посмотреть сообщение
Мало того, что вам не гарантируют совместимость между си++ библиотеками от разных компиляторов
Т.е. если один .obj создан на компиляторе Microsoft, а другой на clang или g++, то они не соберутся в единый файл проекта?
0
18.02.2024, 08:32

Не по теме:

Цитата Сообщение от Liss29 Посмотреть сообщение
если один .obj создан на компиляторе Microsoft, а другой на clang или g++, то они не соберутся в единый файл проекта?
Если оба собраны одним и тем же компилятором, но по-разному, то тоже могут не собраться.
Windows Batch file
1
cl main.obj create.obj
Code
1
2
3
4
5
6
7
8
9
Оптимизирующий компилятор Microsoft (R) C/C++ версии 19.29.xxxxxx для x86
 
/out:main.exe
main.obj
create.obj
main.obj : error LNK2019: ссылка на неразрешенный внешний символ "int __cdecl Create(void)" (?Create@@YAHXZ) в функции _main.
  Указание на символы, которые определены и могут подойти:
    "int __fastcall Create(void)" (?Create@@YIHXZ)
main.exe : fatal error LNK1120: неразрешенных внешних элементов: 1
cl /Gd /c create.cpp
C++
1
2
3
4
// create.cpp
int Create(){
    return 7;
}
cl /Gr /c main.cpp
C++
1
2
3
4
5
// main.cpp
int main(){
    int Create();
    return Create();
}

0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
18.02.2024, 14:20
Цитата Сообщение от Liss29 Посмотреть сообщение
А что столь интеллектуальная библиотека COM не создаёт внутри себя подобного?!
Не создаёт. Сами делайте массив (структуру) с указателями и сами его заполняйте.
Либо выбирайте язык программирования где за вас это делает компилятор.
Цитата Сообщение от Liss29 Посмотреть сообщение
C++
1
2
3
4
5
6
7
//Задание типов указателей на функции 
typedef void* (*PFNALLOC)(ULONG);
typedef void* (*PFNREALLOC)(void*, ULONG);
typedef void* (*PFNFREE)(void*);
typedef void* (*PFNGERSIZE)(void*);
typedef void* (*PFNDIDALLOC)(void*);
typedef void* (*PFNHEAPMINIMIZE)(void);
Ошибки в типах принимаемых и возвращаемых значений. Исправляйте.

Добавлено через 6 минут
Цитата Сообщение от Liss29 Посмотреть сообщение
А что столь интеллектуальная библиотека COM не создаёт внутри себя подобного?!
Напоминаю: вы сами пишете эту интеллектуальную библиотеку. Библиотеки ещё не существует, и тот кто не существует не может создавать и заполнять Vtable.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
18.02.2024, 21:41  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Если оба собраны одним и тем же компилятором, но по-разному, то тоже могут не собраться.
А если оба собираются для релиз-версии одинакового стандарта языка, например std=C++11, то соберутся ли два .obj-файла один из которых компилировался компилятором Microsoft, а другой g++? Если нет, то почему, двоичный код разный что ли?

Цитата Сообщение от Замабувараев Посмотреть сообщение
Напоминаю: вы сами пишете эту интеллектуальную библиотеку. Библиотеки ещё не существует, и тот кто не существует не может создавать и заполнять Vtable.
А как же вот это объявление в ObjIdlbase.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef struct IMallocVtbl
    {
        BEGIN_INTERFACE
        
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
            IMalloc * This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */ 
            _COM_Outptr_  void **ppvObject);
        //.....
        END_INTERFACE
    } IMallocVtbl;
 
    interface IMalloc
    {
        CONST_VTBL struct IMallocVtbl *lpVtbl;
    };
Что делать нужно? В Си нет виртуальных функций и наследования тоже нет, насколько я знаю.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
18.02.2024, 22:56
Цитата Сообщение от Liss29 Посмотреть сообщение
А как же вот это объявление в ObjIdlbase.h:
Это декларация интерфейса. Декларации код не создают.
Цитата Сообщение от Liss29 Посмотреть сообщение
В Си нет виртуальных функций и наследования тоже нет
В С++ за вас это делает компилятор, а в си вы должны делать самостоятельно. Наследование:
C
1
2
3
4
5
6
7
8
9
10
11
/* структура которая будет реализовывать интерфейс */
struct ExampleClass {
    /* так выглядит наследование в си */
    IMallocVtbl *lpVtbl;
    /* если нужно унаследоваться от других интерфейсов, добавляем ещё ссылки на Vtable других интерфейсов */
    /* поля */
    /* счётчик ссылок */
    ULONG ReferenceCounter;
    /* добавить любые данные которые нужны */
 
};
После того как вы выделяете память для структуры struct ExampleClass, вам необходимо инициализировать lpVtbl указателем на виртуальную таблицу.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
19.02.2024, 04:37  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Это декларация интерфейса
Декларация и объявление это не одно и тоже? Я говорю тоже самое другими словами.

Цитата Сообщение от Замабувараев Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
/* структура которая будет реализовывать интерфейс */
struct ExampleClass {
    /* так выглядит наследование в си */
    IMallocVtbl *lpVtbl;
    /* если нужно унаследоваться от других интерфейсов, добавляем ещё ссылки на Vtable других интерфейсов */
    /* поля */
    /* счётчик ссылок */
    ULONG ReferenceCounter;
    /* добавить любые данные которые нужны */
};
Не понял, а реализовывать то функции где, в этой же структуре...

Цитата Сообщение от Замабувараев Посмотреть сообщение
После того как вы выделяете память для структуры struct ExampleClass, вам необходимо инициализировать lpVtbl указателем на виртуальную таблицу.
Так ли?
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
void* DAlloc(ULONG cb)
{
    return HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cb);
}
 
 
void* DRealloc(void* pv, ULONG cb)
{
    return HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pv, cb);
}
 
BOOL DFree(void* pv)
{
    return HeapFree(hHeap, HEAP_ZERO_MEMORY, pv);
}
 
SIZE_T DGetSize(LPCVOID pv)
{
    return HeapSize(hHeap, HEAP_ZERO_MEMORY, pv);
}
 
BOOL DDidAlloc(LPCVOID pv)
{
    PROCESS_HEAP_ENTRY phe = {0};
    while(HeapWalk(hHeap, &phe))
    {
        if(phe.lpData == pv)
            return TRUE;
    }
    
    return FALSE;
}
 
SIZE_T DHeapMinimize(VOID)
{
    return HeapCompact(hHeap, HEAP_ZERO_MEMORY);
}
 
 
//Задание типов указателей на функции 
typedef void* (*PFNALLOC)(ULONG);
typedef void* (*PFNREALLOC)(void*, ULONG);
typedef BOOL (*PFNFREE)(void*);
typedef SIZE_T (*PFNGETSIZE)(void*);
typedef BOOL (*PFNDIDALLOC)(void*);
typedef SIZE_T (*PFNHEAPMINIMIZE)(void);
 
//Определение структуры с указателями на функции.
typedef struct tagALLOCATOR
{
    PFNALLOC          Alloc = DAlloc;
    PFNREALLOC        Realloc = DRealloc;
    PFNFREE           Free = DFree;
    PFNGETSIZE        GetSize = DGetSize;
    PFNDIDALLOC       DidAlloc = DDidAlloc;
    PFNHEAPMINIMIZE   HeapMinimize = DHeapMinimize;
} ALLOCATOR;
 
    
 
ALLOCATOR imalloc = { Alloc, Realloc, Free, GetSize, DidAlloc, 
                      HeapMinimize };
                      
ALLOCATOR* FetchAllocator()
{
    return &imalloc;
}
 
/* структура которая будет реализовывать интерфейс */
struct ExampleClass {
    /* так выглядит наследование в си */
    IMallocVtbl *lpVtbl;
    
    /* если нужно унаследоваться от других интерфейсов, добавляем ещё ссылки на Vtable других интерфейсов */
    /* поля */
    /* счётчик ссылок */
    ULONG RefCount;
    /* добавить любые данные которые нужны */
 
};
 
 
 
ExampleClass* pEx = (ExampleClass*)malloc(sizeof(ExampleClass));
pEx.lpVtbl = (IMallocVtbl*)FetchAllocator();
 
//...
free(pFn);
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
19.02.2024, 06:18
Цитата Сообщение от Liss29 Посмотреть сообщение
Так ли?
C
1
2
3
4
5
 HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
            IMalloc * This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */ 
            _COM_Outptr_  void **ppvObject);
Без первого параметра This как бы функции получили доступ к RefCount и
любым другим данным экземпляра, которые нужны?

Добавлено через 4 минуты

Не по теме:

Цитата Сообщение от Liss29 Посмотреть сообщение
соберутся ли два .obj-файла один из которых компилировался компилятором Microsoft, а другой g++? Если нет, то почему, двоичный код разный что ли?
Какой двоичный код?
Этот?
PowerShell
1
type create.obj
Code
1
2
3
4
5
Lu”Сeu.drectve/ґ
.debug$Shг@B.text$mn
K P`.chks64 U
   /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" с[C:\test\create.obj:<"ВuВuMicrosoft (R) Optimizing CompilerU‹мё]Г'ї‘I:NќЬ«.ZТ&БLЄ@comp.idВuяя@feat.00‘Ђяя@vol.mdяя.drectve/.debug$Sh.text$mn
ЬbҐl .chks64 ?Create@@YIHXZ

0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
19.02.2024, 07:17  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Без первого параметра This как бы функции получили доступ к RefCount и
любым другим данным экземпляра, которые нужны?
Не знаю, я так понимаю показать трудно.

Цитата Сообщение от politoto Посмотреть сообщение
Какой двоичный код?
Любой.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
19.02.2024, 21:08
Цитата Сообщение от Liss29 Посмотреть сообщение
ALLOCATOR imalloc = { Alloc, Realloc, Free, GetSize, DidAlloc,
                      HeapMinimize };
Забыли про QueryInterface, AddRef и Release? Исправляйте.

Добавлено через 2 минуты
Цитата Сообщение от Liss29 Посмотреть сообщение
void* DAlloc(ULONG cb)
Цитата Сообщение от Liss29 Посмотреть сообщение
void* DRealloc(void* pv, ULONG cb)
Напоминаю уже четвёртый раз: типы данных неправильные. Исправляйте.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
19.02.2024, 23:41  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Забыли про QueryInterface, AddRef и Release? Исправляйте.
Прям исправлять, исправлять?! Ну, тогда как-то так:
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* структура которая будет реализовывать интерфейс */
struct ExampleClass {
    /* так выглядит наследование в си */
    IMallocVtbl *lpVtbl;
    
    /* если нужно унаследоваться от других интерфейсов, добавляем ещё ссылки на Vtable других интерфейсов */
    /* поля */
    /* счётчик ссылок */
    ULONG RefCount;
    /* добавить любые данные которые нужны */
 
};
 
ULONG DAddRef(ExampleClass* this)
{
    return this->RefCount++;
}
 
ULONG DRelease(ExampleClass* this)
{
    if(0 != --this->RefCount)
        return this->RefCount;
    
    free(this);
    
    return 0;
}
 
HRESULT DQueryInterface(ExampleClass* this, const REFIID riid, (void**)&ppvObj)
{
    *ppvObj = NULL;
    
    if(riid == IID_IUNKNOWN)
        *ppvObj = static_cast<LPUNKNOWN>(this);
    if(riid == IID_IMALLOC)
        *ppvObj = static_cast<LPMALLOC>(this);
    if(*ppvObj == NULL)
    {
        //Interface not supported 
        return E_NOINTERFACE;
    }   
    else 
    {
        //Interface supported, so increment reference count
        ((LPUNKNOWN)*ppvObj)->AddRef();
        return S_OK;
    }
}
 
 
void* DAlloc(ExampleClass* this, SIZE_T cb)
{
    return HeapAlloc(this->hHeap, HEAP_ZERO_MEMORY, cb);
}
 
 
void* DRealloc(ExampleClass* this, void* pv, SIZE_T cb)
{
    return HeapReAlloc(this->hHeap, HEAP_ZERO_MEMORY, pv, cb);
}
 
BOOL DFree(ExampleClass* this, void* pv)
{
    return HeapFree(this->hHeap, HEAP_ZERO_MEMORY, pv);
}
 
SIZE_T DGetSize(ExampleClass* this, LPCVOID pv)
{
    return HeapSize(this->hHeap, HEAP_ZERO_MEMORY, pv);
}
 
BOOL DDidAlloc(ExampleClass* this, LPCVOID pv)
{
    PROCESS_HEAP_ENTRY phe = {0};
    while(HeapWalk(this->hHeap, &phe))
    {
        if(phe.lpData == pv)
            return TRUE;
    }
    
    return FALSE;
}
 
SIZE_T DHeapMinimize(ExampleClass* this, VOID)
{
    return HeapCompact(this->hHeap, HEAP_ZERO_MEMORY);
}
 
 
//Задание типов указателей на функции 
typedef ULONG (*PFNADDREF(ExampleClass*);
typedef ULONG (*PFNRELEASE(ExampleClass*);
typedef HRESULT (*PFNQUERYINTERFACE(ExampleClass*, const REFIID, void**);
typedef void* (*PFNALLOC)(ULONG);
typedef void* (*PFNREALLOC)(void*, ULONG);
typedef BOOL (*PFNFREE)(void*);
typedef SIZE_T (*PFNGETSIZE)(void*);
typedef BOOL (*PFNDIDALLOC)(void*);
typedef SIZE_T (*PFNHEAPMINIMIZE)(void);
 
//Определение структуры с указателями на функции.
typedef struct tagALLOCATOR
{
    //IUnknown Interface 
    PFNADDREF         AddRef = DAddRef;
    PFNRELEASE        Release = DRelease;
    PFNQUERYINTERFACE QueryInterface = DQueryInterface;
    
    
    //IMalloc Interface
    PFNALLOC          Alloc = DAlloc;
    PFNREALLOC        Realloc = DRealloc;
    PFNFREE           Free = DFree;
    PFNGETSIZE        GetSize = DGetSize;
    PFNDIDALLOC       DidAlloc = DDidAlloc;
    PFNHEAPMINIMIZE   HeapMinimize = DHeapMinimize;
} ALLOCATOR;
 
    
 
ALLOCATOR imalloc = { AddRef, Release, QueryInterface, Alloc, 
                      Realloc, Free, GetSize, DidAlloc, HeapMinimize };
                      
ALLOCATOR* FetchAllocator()
{
    return &imalloc;
}
 
ExampleClass* pEx = (ExampleClass*)malloc(sizeof(ExampleClass));
pEx->lpVtbl = (IMallocVtbl*)FetchAllocator();
 
//...
free(pFn);
Добавлено через 38 минут
Что значит появление таких ошибок в функции CoCreateInstance?

C++
1
2
3
4
5
6
7
8
9
//{308D0430-1090-11CF-B92A-00AA006238F8}
DEFINE_GUID(CLSID_ALLOCATOR, 0x308D0430, 0x1090, 0x11cf, 0xb9,
                             0x2a, 0x0, 0xaa, 0x0, 0x38, 0xf8);
HRESULT hr =
                CoCreateInstance(CLSID_ALLOCATOR,
                    NULL,
                    CLSCTX_INPROC_SERVER,
                    IID_IMalloc,
                    (void**)&pMalloc);
Code
1
error C2440: функция: невозможно преобразовать "const GUID" в "const IID *const "
Code
1
warning C4024: CoCreateInstance: различные типы для формального и фактического параметров 1
Что опять не нравится компилятору... нужно явное преобразование или что?
0
 Аватар для Morgot
336 / 129 / 18
Регистрация: 26.12.2010
Сообщений: 501
20.02.2024, 01:18
Цитата Сообщение от Liss29 Посмотреть сообщение
невозможно преобразовать "const GUID" в "const IID *const "
Может оно указатель хочет, судя по ошибке?
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
20.02.2024, 04:36  [ТС]
Цитата Сообщение от Morgot Посмотреть сообщение
Может оно указатель хочет, судя по ошибке?
Может быть, но эта библиотечная функция, как задать нужные параметры вот в чём вопрос.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
20.02.2024, 05:35
Цитата Сообщение от Liss29 Посмотреть сообщение
Может быть, но эта библиотечная функция, как задать нужные параметры вот в чём вопрос.
Забыли взять указатель на CLSID_ALLOCATOR? Должно быть &CLSID_ALLOCATOR. Исправляйте.

Добавлено через 38 секунд
Аналогично для всяких IID_IMalloc: нужно взять указатель.

Добавлено через 4 минуты
Цитата Сообщение от Liss29 Посмотреть сообщение
typedef void* (*PFNALLOC)(ULONG);
typedef void* (*PFNREALLOC)(void*, ULONG);
В пятый раз идём по кругу? Почему вы упорно отказываетесь исправлять типы параметров?

Добавлено через 3 минуты
Цитата Сообщение от Liss29 Посмотреть сообщение
*ppvObj = static_cast<LPUNKNOWN>(this);
Дикая смесь между си и си++. Удаляйте.

Добавлено через 12 минут
Цитата Сообщение от Liss29 Посмотреть сообщение
IID_IUNKNOWN IID_IMALLOC
Нет таких типов данных. Забыли что язык си регистрозависимый? Исправляйте на IID_IUnknown и IID_IMalloc.
Цитата Сообщение от Liss29 Посмотреть сообщение
if(riid == IID_IUNKNOWN)
И этот оператор сравнения. Опять забыли на каком языке пишете? Это си. Должно быть так «if(IsEqualIID(riid, &IID_IUnknown))»
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
20.02.2024, 05:44
Цитата Сообщение от Liss29 Посмотреть сообщение
Что опять не нравится компилятору...
Компилятору Си или c+?

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 <windows.h>
 
int 
main() {
    // CoInitializeXXX etc..
    LPVOID instance = 0;
    HRESULT hr = CoCreateInstance( 
#ifdef __cplusplus        
// С++
            CLSID_TypeLibRegistrationReader,
            0, CLSCTX_INPROC_SERVER,
            IID_ITypeLibRegistration,
#else 
// Си
            &CLSID_TypeLibRegistrationReader,
            0, CLSCTX_INPROC_SERVER,
            &IID_ITypeLibRegistration,
#endif            
            &instance
        );
    
    return hr;
 
}
 
#pragma comment(lib, "ole32")
Добавлено через 1 минуту
Windows Batch file
1
2
cl /Tp refguid.c /nologo
cl /Tc refguid.c /nologo
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
20.02.2024, 06:12  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Забыли взять указатель на CLSID_ALLOCATOR? Должно быть &CLSID_ALLOCATOR. Исправляйте.
Если добавить оператор взятия адреса, то да, ошибки, которые я выкладывал ранее исчезли, проект собрался. Но правда, при старте проекта при попытке выделения памяти появляется ошибка "Error: No allocator", короче говоря функция CoCreateInstance не отрабатывает.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
case IDM_CREATE:
        {
            HRESULT hr =
                CoCreateInstance(&CLSID_ALLOCATOR,
                    NULL,
                    CLSCTX_INPROC_SERVER,
                    &IID_IMalloc,
                    (void**)&pMalloc);
 
            if (FAILED(hr))
            {
                MessageBox(hwnd, TEXT("Error: No allocator"),
                    szAppName, MB_OK);
                return 0;
            }
 
            InvalidateRect(hwnd, NULL, TRUE);
            return 0;
        }
Цитата Сообщение от Замабувараев Посмотреть сообщение
В пятый раз идём по кругу? Почему вы упорно отказываетесь исправлять типы параметров?
Цитата Сообщение от Замабувараев Посмотреть сообщение
Дикая смесь между си и си++. Удаляйте.
Сейчас точно всё должно быть исправлено.
Кликните здесь для просмотра всего текста
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* структура которая будет реализовывать интерфейс */
struct ExampleClass {
    /* так выглядит наследование в си */
    IMallocVtbl *lpVtbl;
    
    /* если нужно унаследоваться от других интерфейсов, добавляем ещё ссылки на Vtable других интерфейсов */
    /* поля */
    /* счётчик ссылок */
    ULONG RefCount;
    HANDLE hHeap;
    /* добавить любые данные которые нужны */
 
};
 
ULONG DAddRef(ExampleClass* this)
{
    return this->RefCount++;
}
 
ULONG DRelease(ExampleClass* this)
{
    if(0 != --this->RefCount)
        return this->RefCount;
    
    free(this);
    
    return 0;
}
 
HRESULT DQueryInterface(ExampleClass* this, const REFIID riid, (void**)&ppvObj)
{
    *ppvObj = NULL;
    
    if(riid == IID_IUnknown)
        *ppvObj = (LPUNKNOWN)this;
    if(riid == IID_IMalloc)
        *ppvObj = (LPMALLOC)this;
    if(*ppvObj == NULL)
    {
        //Interface not supported 
        return E_NOINTERFACE;
    }   
    else 
    {
        //Interface supported, so increment reference count
        ((LPUNKNOWN)*ppvObj)->AddRef();
        return S_OK;
    }
}
 
 
void* DAlloc(ExampleClass* this, SIZE_T cb)
{
    return HeapAlloc(this->hHeap, HEAP_ZERO_MEMORY, cb);
}
 
 
void* DRealloc(ExampleClass* this, void* pv, SIZE_T cb)
{
    return HeapReAlloc(this->hHeap, HEAP_ZERO_MEMORY, pv, cb);
}
 
BOOL DFree(ExampleClass* this, void* pv)
{
    return HeapFree(this->hHeap, HEAP_ZERO_MEMORY, pv);
}
 
SIZE_T DGetSize(ExampleClass* this, LPCVOID pv)
{
    return HeapSize(this->hHeap, HEAP_ZERO_MEMORY, pv);
}
 
BOOL DDidAlloc(ExampleClass* this, LPCVOID pv)
{
    PROCESS_HEAP_ENTRY phe = {0};
    while(HeapWalk(this->hHeap, &phe))
    {
        if(phe.lpData == pv)
            return TRUE;
    }
    
    return FALSE;
}
 
SIZE_T DHeapMinimize(ExampleClass* this, VOID)
{
    return HeapCompact(this->hHeap, HEAP_ZERO_MEMORY);
}
 
 
//Задание типов указателей на функции 
typedef ULONG (*PFNADDREF(ExampleClass*);
typedef ULONG (*PFNRELEASE(ExampleClass*);
typedef HRESULT (*PFNQUERYINTERFACE(ExampleClass*, const REFIID, void**);
typedef void* (*PFNALLOC)(ExampleClass*, SIZE_T);
typedef void* (*PFNREALLOC)(ExampleClass*, void*, SIZE_T);
typedef BOOL (*PFNFREE)(ExampleClass*, void*);
typedef SIZE_T (*PFNGETSIZE)(ExampleClass*, void*);
typedef BOOL (*PFNDIDALLOC)(ExampleClass*, void*);
typedef SIZE_T (*PFNHEAPMINIMIZE)(ExampleClass*, void);
 
//Определение структуры с указателями на функции.
typedef struct tagALLOCATOR
{
    //IUnknown Interface 
    PFNADDREF         AddRef = DAddRef;
    PFNRELEASE        Release = DRelease;
    PFNQUERYINTERFACE QueryInterface = DQueryInterface;
    
    
    //IMalloc Interface
    PFNALLOC          Alloc = DAlloc;
    PFNREALLOC        Realloc = DRealloc;
    PFNFREE           Free = DFree;
    PFNGETSIZE        GetSize = DGetSize;
    PFNDIDALLOC       DidAlloc = DDidAlloc;
    PFNHEAPMINIMIZE   HeapMinimize = DHeapMinimize;
} ALLOCATOR;
 
    
 
ALLOCATOR imalloc = { AddRef, Release, QueryInterface, Alloc, 
                      Realloc, Free, GetSize, DidAlloc, HeapMinimize };
                      
ALLOCATOR* FetchAllocator()
{
    return &imalloc;
}
 
ExampleClass* pEx = (ExampleClass*)malloc(sizeof(ExampleClass));
pEx->lpVtbl = (IMallocVtbl*)FetchAllocator();
 
//...
free(pFn);


Добавлено через 3 минуты
Цитата Сообщение от politoto Посмотреть сообщение
Компилятору Си или c+?
Этот файл, который выдавал ошибки, на Си, библиотека DLL на С++. Ну, как в оригинале автора то бишь Петзольда.
0
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,128
20.02.2024, 07:35
Цитата Сообщение от Liss29 Посмотреть сообщение
функция CoCreateInstance не отрабатывает
Смотрите как работает создание объекта в COM.
1) COM нужны апартаменты (apartments), поэтому при полноценной работе с COM вы должны для каждого использующего COM потока вызвать CoInitialize или CoInitializeEx.
2) Все COM библиотеки экспортируют одну и ту же предопределённую функцию. Когда возникает необходимость библиотека загружается динамически и с помощью этой функции из неё создаётся нужный объект.
3) При инсталляции COM-библиотеки в систему в особый раздел реестра прописывается информация связывающая CLSID и имя библиотеки.
4) При вызове CoCreateInstance производится поиск в реестре по запрошенному CLSID, находится связанный с CLSID файл-библиотеки, выполняется динамическая загрузка найденной библиотеки, из неё достаётся адрес предопределённой функции и с помощью неё уже производится создание нужного объекта.

Вы уверены, что сделали полноценный COM, зарегистрировали его, создали апартаменты? Исходный пример был ещё очень далёк от COM и выступал лишь в целях демонстрации некоторых его моментов.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.02.2024, 07:35

Access and Excel OLE object
Помогите пожалуста!!!! Как вставить рисунок с OLE object (Image) таблицы EXCEL в таблицу Acces , c помошью макроса в среде ...

ActiveX ole-object с Delphi на Qt
Всем привет. Стоит задача перенести код взаимодействия с OLE-объектами, с Delphi на QT. Вроде ничего необычного, н оне могу достучаться до...

Access and Excel OLE object
Как вствить содержимое image1 в таблицу Accecss ? И как отобразить рисунок на форме Access? Dim etr As Object Dim wbk As...

Импорт файла из OLE Object в attachment
Здравствуйте. В старой БД есть поле типа OLE Object, которое содержит изображения в формате .jpg. Показать на форме это изображение...

Как вставить рисунок с OLE object таблицы EXCEL в таблицу Acces
Как в VBA вставить рисунок с OLE object таблицы EXCEL в таблицу Acces или в другой Excel fayl


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

Или воспользуйтесь поиском по форуму:
120
Ответ Создать тему
Новые блоги и статьи
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал (мат мет мод 29)
anaschu 23.06.2026
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал Материалы для обсуждения с МГСУ · 2026 Рисунки внутри приложенного ворд файла. Что за. . .
28. Конкретное развертывание плана номер 1 из поста номер 27
anaschu 22.06.2026
Можно ли из модели получить конкретные строительные требования? Честно — напрямую из текущей модели такие ответы не получить. Но цепочка логики есть, и она не такая длинная. Где разрыв . . .
27. Планы на разработку функциональных требований к строительству внутри модели пищеблока (или не только его?)
anaschu 22.06.2026
Что уже реализовано и даёт конфликты «бесплатно» Самый простой конфликт уже работает — конфликт за ресурс-работника. Заданий больше, чем доступных поваров → очередь в queue1. Это прямое отражение. . .
26. мед мат модель.Какие типы конфликтов функциональных требований можно рассчитать через ДЕС-моделирование (СМО) в AnyLogic?
anaschu 22.06.2026
Что ДЕС/ СМО умеет считать напрямую: Конфликты за ресурсы (очереди, узкие места). Несколько типов агентов (повара, учителя, рабочие, пациенты) претендуют на один ресурс (лифт, вход, коридор,. . .
25 модель здравосохранения и функциональных требований к пищеблоку: конфликты функциональных требований.
anaschu 22.06.2026
Есть ли данные о том, какие функциональные/ эксплуатационные требования или их сочетания труднее всего учитывать при проектировании зданий? Да, такие данные есть, и они хорошо описаны и в российской,. . .
Remote Connection Manager
DevAlt 21.06.2026
Написал для себя небольшую прилагу: https:/ / github. com/ altbodhi/ ReConMan По итогу пришел к мысли, что DU не дружат с существующими технологиями. От сериализации до отображения в реляционную. . .
Администрация Хабра удаляет новые энергоэфективные алгоритмы, которые не западной школы кода, и вовсе никак не сгенерированы
Hrethgir 20.06.2026
Делается это, как замечено, при правках - при объявлении концептуальных отличий в алгоримах. Делается это, по линейке событий - после дополнения публикации основными отличиями от основных западных. . .
Процесс ориентированная диалектика (не новость - просто системное обновление, философия).
Hrethgir 20.06.2026
Однажды один участник в своём блоге, на этом форуме, сделал запись "О языках замолвите слово". Понимая, что язык - важная вещь, я решил хорошо подумать, прежде чем сказать, и сказал то, что вы видите. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru