979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
1

Создание COM DLL: ошибка в приведении типов

10.07.2015, 18:46. Показов 1738. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здорова!

Читаю про COM, в книге нашел пример Пример EX24B - обычная MFC DLL, содержащая настоящую COM-версию класса CSpaceship.

Вот код
Файл INTERFACE.h:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
struct IMotion : public IUnknown
{
    STDMETHOD_(void, Fly) ()=0;
    STDMETHOD_(int&, GetPosition) ()=0;
};
 
struct IVisual : public IUnknown
{
    STDMETHOD_(void,Display) ()=0;
};

Файл SPACESHIP.h
Кликните здесь для просмотра всего текста
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
void ITrace(REFIID iid, const char* str);
 
//////////////////////////////////////////////
//CSpaceship command target
 
class CSpaceship : public CCmdTarget
{
    DECLARE_DYNCREATE(CSpaceship)
 
private:
    int m_nPosition;//доступ к этим переменным возможен из всех интерфейсов
    int m_nAcceleration;
    int m_nColor;
protected:
    CSpaceship();//защищенный конструктор для динамического создания объектов
 
    //Атрибуты
public:
    
    //Операции
public:
 
    //Переопределенные функции
    //переопределенные виртуальные функции, сгенерированные ClassWizard
    //{{AFX_VIRTUAL(CSpaceship)
public:
    virtual void OnFinalRelease();
    //}}AFX_VIRTUAL
 
    //Реализация
protected:
    virtual ~CSpaceship();
 
    //сгенерированные функции таблицы сообщений
    //{{AFX_MSG(CSpaceship)
    //ПРИМЕЧАНИЕ: здесь ClassWizard будет добавлять и удалять функции-члены
    //}}AFX_MSG
 
    DECLARE_MESSAGE_MAP();
    DECLARE_OLECREATE(CSpaceship)
    BEGIN_INTERFACE_PART(Motion,IMotion)
        STDMETHOD_(void,Fly)();
        STDMETHOD_(int&,GetPosition)();
    END_INTERFACE_PART(Motion)
 
    BEGIN_INTERFACE_PART(Visual,IVisual)
        STDMETHOD_(void,Display)();
    END_INTERFACE_PART(Visual)
 
    DECLARE_INTERFACE_MAP()
};
 
//////////////////////////////////////////////////

Файл SPACESHIP.cpp
Кликните здесь для просмотра всего текста
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
135
136
137
138
139
140
141
#include "stdafx.h"
#include "MfcDllCom.h"
#include "INTERFACE.h"
#include "SPACESHIP.h"
 
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#endif
//////////////////////////////////////////////////
//CSpaceship
 
//{692D03A-C689-11CE-B337-88EA36DE9E4E}
static const IID IID_IMotion=
{0x692d03a4,0xc689,0x11ce,{0xb3,0x37,0x88,0xae,0x36,0xde,0x9e,0x4e}};
 
//{692D0eA5-C689-11CE-B337-88EA36DE9E4E}
static const IID IID_IVisual=
{0x692d03a5,0xc689,0x11ce,{0xb3,0x37,0x88,0xea,0x36,0xde,0x9e,0x4e}};
 
IMPLEMENT_DYNCREATE(CSpaceship,CCmdTarget)
CSpaceship::CSpaceship()
{
    TRACE("Конструктор CSpaceship\n");
    m_nPosition=100;
    m_nAcceleration=101;
    m_nColor=102;
    //чтобы приложение не завершилось, пока активен COM-объект, конструктор вызывает AfxOleLockApp
    AfxOleLockApp();
}
 
CSpaceship::~CSpaceship()
{
    TRACE("ДеструкторCSpaceship\n");
    //чтобы завершить приложение после уничтожения всех созданных COM-объектов,
    //деструктор вызывает AfxOleUnlockApp
    AfxOleUnlockApp();
}
 
void CSpaceship::OnFinalRelease()
{
    //OnFinalRelease вызывается, когда освобождается последняя ссылка на COM-объект
    //Эта реализация уничтожает объект. Добавьте необходимую для вашего объекта очистку
    //перед удалением его из памяти.
 
    delete this;
}
BEGIN_MESSAGE_MAP(CSpaceship,CCmdTarget)
    //{{AFX_MSG_MAP(CSpaceship)
    //ПРИМЕЧАНИЕ: здесь ClassWizard будет добавлять и удалять макросы
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
 
BEGIN_INTERFACE_MAP(CSpaceship,CCmdTarget)
    INTERFACE_PART(CSpaceship,IID_IMotion,Motion)
    INTERFACE_PART(CSpaceship,IID_IVisual,Visual)
END_INTERFACE_MAP()
 
//(692D03A3-C689-11CE-8337-88FA360E9E4E}
IMPLEMENT_OLECREATE(CSpaceship,"Spaceship",0x692d03a3,0xc689,
    0x11ce,0xb3,0x37,0x88,0xea,0x36,0xde,0x9e,0x4e)
STDMETHODIMP_(ULONG) CSpaceship::XMotion::AddRef()
{
    TRACE("CSpaceship::XMotion::AddRef\n");
    METHOD_PROLOGUE(CSpaceship,Motion)
        return pThis->ExternalAddRef();
}
 
STDMETHODIMP_(ULONG) CSpaceship::XMotion::Release()
{
    TRACE("CSpaceship::XMotion::Release\n");
    METHOD_PROLOGUE(CSpaceship,Motion)
    return pThis->ExternalRelease();
}
 
STDMETHODIMP CSpaceship::XMotion::QueryInterface(REFIID iid, LPVOID* ppvObj)
{
    ITrace(iid, "CSpaceship::XMotion::QueryInterface");
    METHOD_PROLOGUE(CSpaceship,Motion)
    return pThis->ExternalQueryInterface(iid,ppvObj);
}
 
STDMETHODIMP_(void) CSpaceship::XMotion::Fly()
{
    TRACE("CSpaceship::XMotion::Fly\n");
    METHOD_PROLOGUE(CSpaceship,Motion)
    TRACE("m_nPosition=%d\n",pThis->m_nPosition);
    TRACE("m_nAcceleration=%d\n",pThis->m_nAcceleration);
    return;
}
 
STDMETHODIMP_(int&) CSpaceship::XMotion::GetPosition()
{
    TRACE("CSpaceship::XMotion::GetPosition\n");
    METHOD_PROLOGUE(CSpaceship,Motion)
    TRACE("m_nPostion=%d\n",pThis->m_nPosition);
    TRACE("m_nAcceleration=%d\n",pThis->m_nAcceleration);
    return pThis->m_nPosition;
}
/////////////////////////////////////////////
STDMETHODIMP_(ULONG) CSpaceship::XVisual::AddRef()
{
    TRACE("CSpaceship::XVisual::AddRef\n");
    METHOD_PROLOGUE(CSpaceship,Visual)
        return pThis->ExternalAddRef();
}
 
STDMETHODIMP_(ULONG) CSpaceship::XVisual::Release()
{
    TRACE("CSpaceship::XVisual::Release\n");
    METHOD_PROLOGUE(CSpaceship,Visual)
    return pThis->ExternalRelease();
}
 
STDMETHODIMP CSpaceship::XVisual::QueryInterface(REFIID iid, LPVOID* ppvObj)
{
    ITrace(iid,"CSpaceship::XVisual::QueryInterface");
    METHOD_PROLOGUE(CSpaceship,Visual)
    return pThis->ExternalQueryInterface(iid,ppvObj);
}
 
STDMETHODIMP_(void) CSpaceship::XVisual::Display()
{
    TRACE("CSpaceship::XVisual::Display\n");
    METHOD_PROLOGUE(CSpaceship,Visual)
    TRACE("m_nPosition=%d\n",pThis->m_nPosition);
    TRACE("m_nColor=%d\n",pThis->m_nColor);
}
 
/////////////////////////////////////
void ITrace(REFIID iid, const char* str)
{
    OLECHAR* lpszIID;
    ::StringFromIID(iid, &lpszIID);
    CString strTemp=(LPCWSTR) lpszIID;
    TRACE("%s - %s\n",(const char*) strTemp, (const char*) str);
    AfxFreeTaskMem(lpszIID);
}
 
///////////////////////////////
//Обработчики сообщений класа CSpaceship


И когда компилирую получаю ошибки:
Кликните здесь для просмотра всего текста

SPACESHIP.cpp
1>d:\visual studio 2010\projects\mfcdllcom\mfcdllcom\spaceship.cpp(80): error C2664: CCmdTarget::ExternalQueryInterface: невозможно преобразовать параметр 1 из "const IID" в "const void *"
1> Для выполнения данного преобразования нет доступного оператора преобразования, определенного пользователем, или вызов оператора невозможен
1>d:\visual studio 2010\projects\mfcdllcom\mfcdllcom\spaceship.cpp(119): error C2664: CCmdTarget::ExternalQueryInterface: невозможно преобразовать параметр 1 из "const IID" в "const void *"
1> Для выполнения данного преобразования нет доступного оператора преобразования, определенного пользователем, или вызов оператора невозможен
1>d:\visual studio 2010\projects\mfcdllcom\mfcdllcom\spaceship.cpp(136): error C2440: приведение типов: невозможно преобразовать "CString" в "const char *"
1> Для выполнения данного преобразования нет доступного оператора преобразования, определенного пользователем, или вызов оператора невозможен
1>
1>СБОЙ построения.


Как можно перевести const IID в const void* ??? Ошибка в этом коде:
C++
1
2
3
4
5
6
STDMETHODIMP CSpaceship::XMotion::QueryInterface(REFIID iid, LPVOID* ppvObj)
{
    ITrace(iid, "CSpaceship::XMotion::QueryInterface");
    METHOD_PROLOGUE(CSpaceship,Motion)
    return pThis->ExternalQueryInterface(iid,ppvObj);//в этой строк нужно преобразовать.
}
???????

Добавлено через 4 часа 42 минуты
Ну так что? Кто этот пример разбирал? В книге там этот пример для VS6, а я набрал его в VS10, мб. из за этого ошибки вылазят?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.07.2015, 18:46
Ответы с готовыми решениями:

Ошибка в приведении типов
Здравствуйте. Я недавно начал самостоятельно изучать программирование Win32 приложений, и у меня...

О приведении типов и классов
Читая про приведение типов из msdn наткнулся на фразу Этого я, признаюсь, не понял. Производные...

Ну жна помощь в приведении типов
Никак не могу понять как работает приведение типов. В первую очередь про dynamic_cast. Допустим у...

FormatException не обработано при приведении типов
Надоело, просто жесть как надоело: err = Convert.ToInt32(hgg); ferrors = err; Ну что здесь...

6
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
13.07.2015, 20:27  [ТС] 2
В общем исправил эту ошибку, там нужно указатель передавать отак:
C++
1
return pThis->ExternalQueryInterface(&iid,ppvObj);
Но появилась другая ошибка:
1>ClCompile:
1> Для всех выходных данных обновления не требуется.
1> SPACESHIP.cpp
1>d:\visual studio 2010\projects\mfcdllcom\mfcdllcom\spaceship.cpp(136): error C2440: приведение типов: невозможно преобразовать "CString" в "const char *"
1> Для выполнения данного преобразования нет доступного оператора преобразования, определенного пользователем, или вызов оператора невозможен
1>
1>СБОЙ построения.

ошибка в этой функции:
C++
1
2
3
4
5
6
7
8
9
/////////////////////////////////////
void ITrace(REFIID iid, const char* str)
{
    OLECHAR* lpszIID;
    ::StringFromIID(iid, &lpszIID);
    CString strTemp=(LPCWSTR) lpszIID;
    TRACE("%s - %s\n",(const char*)strTemp, (const char*) str);
    AfxFreeTaskMem(lpszIID);
}
не может преобразовать CString strTemp в (const char*), почему не может преобразоваться???? В настройках выставлено использовать кодировку юникод, когда выставляю использовать многобайтную кодировку, то преобразовывается, но появляется другая ошибка уже в этой строчке CString strTemp=(LPCWSTR) lpszIID;, тут оно не может преобразовать LPCWSTR в CString.
Как эту ошибку обойти? Я пока закоментировал строку с ошибкой и так скомпелировал и получил COM DLL, а теперь что с этим COM DLL делать?

Добавлено через 1 минуту
Создал объект DLL COM теперь нужно его как то попытаться использовать но как? ))))

Добавлено через 41 минуту
Я создал тестовый пример и сейчас у меня пишет ошибки:
Не найден Program ID -- ошибка = 800401f3
То есть он не может найти в реестре найти GUID моей COM DLL, как добавить в реестр свою COM???

Добавлено через 6 минут
Как добавить в реестр информацию о MFC COM DLL?

Добавлено через 20 минут
Так что никто не знает как его зарегистрировать? Я добавил dll в windows/system32 и вызвал из меню пуск -> выполнить regsvr32 MfcDllCom.dll , и у меня выводится ошибка:
Создание COM DLL: ошибка в приведении типов


Добавлено через 1 минуту
в книге написано что для того чтобы зарегистрировать dll нужно использовать использовать специальную утилиту с диска под названием REGCOMP где ее брать хз.
0
693 / 303 / 99
Регистрация: 04.07.2014
Сообщений: 846
13.07.2015, 20:50 3
Зачем тебе com? Брось каку.
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
14.07.2015, 08:57  [ТС] 4
Цитата Сообщение от AlexVRud Посмотреть сообщение
Зачем тебе com? Брось каку.
ЧЕ?

Добавлено через 3 минуты
Нашел утилиту RegComp и все рамно она не регистрирует, пишет ошибку:
failed to find dllregisterserver function что делать? что это означает?

Добавлено через 9 минут
Ну так что это значает, не может найти dllRegisterServer, а что это такое?

Добавлено через 10 часов 0 минут
так что никто не знает как зарегистрировать COM компонент?

Добавлено через 30 минут
Создание COM DLL: ошибка в приведении типов

и что делать? как исправлять?

Добавлено через 37 секунд
Я смотрел что эта ошибка означает, это типо у меня неправильный dll. А что делать? как его исправлять?
0
693 / 303 / 99
Регистрация: 04.07.2014
Сообщений: 846
14.07.2015, 10:05 5
Ну а почитать внимательно про процесс создания com-объектов кто будет? Надо не только написать класс. Но и описать интерфейс, сгенерировать прослойку и откомпилить уже все вместе. Ты для начала подбери побольше литературы и найди простой пример.
З.Ы.: если ты сейчас не знаешь зачем тебе com объекты и с чем их едят. Начни с чего-то более простого. Прочитай про REST, ZeroMQ и Т.п.
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
14.07.2015, 10:16  [ТС] 6
Цитата Сообщение от AlexVRud Посмотреть сообщение
Прочитай про REST, ZeroMQ и Т.п.
Ачто это такое? Мне нужно COM и ActiveX разобрать, я хочу в своих программах использовать уже готовые программы и не заморачиватся.
Кстати только что "методом тыка" заработало, зарегистрировал dll и все заработало, проблема была в самой dll, там ее нужно создавать как dll, а я как попало создал

Хороше бы еще рассмотреть пример с COM EXE, с dll разобрались, а как создать теперь COM exe - так называемый внешний компонент. dll это как бы внутренний компонент, а exe внешний.

Да тут еще где на диске должны хранится COM компоненты? От например COM DLL как я понял ее как обычную dll в папке с программой не получится сохранять, ее же ведь нужно регистрировать? Значит что получается ее нужно в windows/system32 закидывать, регистрировать и потом использовать? Вообще то я не пробовал ее запустить из папки программы, но что то мне кажется что из папки программы оно не будет работать, от если я удалю зарегистрированую COM dll из system32 и скопирую ее в папку с программой, то она ж не найдется правильно? Щас проверю

Добавлено через 57 секунд
Цитата Сообщение от AlexVRud Посмотреть сообщение
З.З.Ы.: и ещё, для твоего вопроса есть отдельная ветка https://www.cyberforum.ru/com-ole/
Я не хочу в этой ветке создавать, там людей мало, само больше в С++ для начинающих. Там создай и будешь ждать год пока кто то ответит

Добавлено через 8 минут
Цитата Сообщение от ninja2 Посмотреть сообщение
Щас проверю
Только проверил, удаляю из syste32 и добавляю в папку с программой и не работает, что так оно и должно быть, а почему dll работают? Получается нужно повторно регистрировать dll уже из папки с программой тогда работает.
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,413
14.07.2015, 10:51 7
Цитата Сообщение от ninja2 Посмотреть сообщение
а почему dll работают?
потому что DLL грузит система: при загрузке EXE система находит в нем информацию о том какие DLL и какие функции он использует и загружает эти DLL / получает точки входа в функции (если загрузка не производится "руками" и указано только имя DLL, то в начале поиск DLL идет в папке с EXE затем в системной папке - почему? - так сделали).
DLL в котором живет COM-объект так же загружает система. но причина этой загрузки не запуск EXE, а создание объекта - кто-то где-то в системе создает объект определенного класса, система ищет в реестре запись в которой написано где лежит DLL в котором живет этот объект (запись создается при регистрации), загружает ее и получает от нее ссылку на объект. если вы утащили DLL, то система конечно же не найдет ее.
напрасно вы игнорируете ветку форума посвященную COM - да, в ветке для начинающих больше людей, но и вопрос ваш утонет в потоке проблем-однодневок. больные вашей проблемой люди заходят в соответствующую ветку, а другие вам вряд ли ответят.
пример COM (без обложек) https://www.cyberforum.ru/com-... ost3538077
1
14.07.2015, 10:51
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.07.2015, 10:51
Помогаю со студенческими работами здесь

Изменение значения при приведении типов
Привет форумчане! Вот часть программы: u = 64000; s = (short) u; console.Writeline("s после...

Нахождение ошибки в наследовании и приведении типов
имеется рабочий код на с++, пыталась переделать его в С#, возникают ошибки,которые я не в...

Почему выдает ошибку о приведении типов?
{$reference System.Windows.Forms.dll} {$reference System.Drawing.dll} uses...

Куда деваются байты при приведении типов?
Всем доброго времени суток... Т.к. основной проект на c++, то пишу сюда... Непонятки с приведением...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru