Referat.me

Название: Оформление класса в виде COM объекта в C++

Вид работы: статья

Рубрика: Информатика и программирование

Размер файла: 15.23 Kb

Скачать файл: referat.me-140468.docx

Краткое описание работы: Допустим у вас есть некоторое приложение, написанное на C++(VC++ если быть корректным). Как оно у вас появилось не суть важно, может быть это ваша старая разработка, может быть вы решили сначала отладить предметную часть.

Оформление класса в виде COM объекта в C++

Оформление класса в виде COM объекта.

Допустим у вас есть некоторое приложение, написанное на C++(VC++ если быть корректным). Как оно у вас появилось не суть важно, может быть это ваша старая разработка, может быть вы решили сначала отладить предметную часть. Важно то что вы горите желанием вынести часть классов в объектные модули и оформить их в виде ActiveX, COM и ATL объектов. Есть несколько типовых проблем связанных с таким переносом.

Множественные конструкторы.

class MyCOM

{

MyCOM();

MyCOM(long id);

MyCOM(long id,LPCSTR Name);

:

}

Знакомо и очень удобно, но в COM правила создания объекта строго определены и ни одна из функции для созданий объектов не позволяет передавать параметры конструктору класса.

Настройку объекта придется вынести в отдельный метод например Init.

// IMyCOM cтандартная обертка наследник от COleDispatchDriver

IMyCOM * d=new IMyCOM;

COleException pErr;

CString SSS="Mylib.MyCOM";

d->CreateDispatch( SSS,&pErr);

d->Init(15,"Матрица"); // Инициализируем

В принципе вы можете создать свою фабрику объектов. Это позволит создавать объекты вот так.

IMyOF * d=new IMyOF;

COleException pErr;

CString SSS="MyLib.MyOF";

d->CreateDispatch( SSS,&pErr);

IMyCOM Ob1(d->CraeteEmpty());

IMyCOM Ob2(d->CraeteId(15));

IMyCOM Ob3(d->CraeteFull(15,SSS ));

Но зачем вам лишний промежуточный объект если можно обойтись без него.

Перегруженные методы.

class MyCOM

{

:

LPCSTR GetMyRec(long id);

LPCSTR GetMyRec(LPCSTR Name);

AddRec ();

AddRec (long id);

AddRec (long id, LPCSTR Name);

:.

}

Это вполне законный код С++, но COM не разрешит вам в интерфейсе объявить два метода с одним именем. Это противоречит концепции.

Решение

Можно связать функции с разными методами интерфейса для этого в odl пишим

[id(1)] BSTR AddRecName(BSTR ID);

[id(2)] BSTR AddRecID(long ID);

а в cpp осуществляем привязку.

BEGIN_DISPATCH_MAP(:.)

DISP_FUNCTION(CPSDG, "AddRecName", AddRec, VTS_BSTR, VTS_BSTR)

DISP_FUNCTION(CPSDG, "AddRecId", AddRec, VTS_BSTR, VTS_I2)

DISP_FUNCTION_ID(:.)

END_DISPATCH_MAP()

Можно написать прокси функции. Например для GetMyRec прототип может выглядеть так

LPCSTR GetMyRec (VARIANT id)

{

switch id.vt

{case VT_I4: { return GetMyRec(id.lVal); }

case VT_BSTR: { return GetMyRec(id.bstrVal); }

}

return S_OK;

}

Для функции AddRec можно сделать вот так

HRESULT AddRec (VARIANT id, VARIANT Name)

{

if ((id.vt==VT_EMPTY)&&(Name.vt==VT_EMPTY))

{AddRec() ; return S_OK;}

if ((id.vt==VT_I4)&&(Name.vt==VT_EMPTY))

{AddRec(id.lVal) ; return S_OK;}

if ((id.vt==VT_I4)&&(Name.vt== VT_BSTR))

{AddRec(id.lVal, Name. bstrVal ) ; return S_OK;}

:

}

Этого вполне достаточно, но можно еще изменить объявление метода интерфейса в odl вот так

HRESULT Add(VARIANT [optional, in]id, [optional,in]VARIANT S);

это позволит вызывать метод , более красиво.

Пример на VB

MyObject.Add // Любой из вариантов должен работать

MyObject.Add 15

MyObject.Add 15, "Var"

Пользовательские типы данных

В сложном проекте полно собственных констант, структур, множеств используемых в качестве параметров .

#define IDL_NEXT 5

#define IDL_STOP 6

:

struct UDT

{

unsigned long X;

unsigned long Y;

BSTR pbstr;

} UDT;

:

typedef enum EnumType

{

First=1,

Seond=4,

Last =10

};

class MyCOM

{

:.

void SetType (EnumType T);

void Do(UDT * Dat);

void SetMove (int val);

:.

}

:

// а где то все это вызывается

SetType(First);

UDT Dat,Dat1;

:

Do (&Dat,Dat1);

SetMove (IDL_NEXT);

Понятно что, для того чтобы подобным образом можно было вызывать методы COM объекта, служебные структуры, множества и константы должны быть доступны из вне.

Для этого нужно включить их описание в ODL файл.

Множества описываются так.

[

uuid(...),

version(1.0),

helpstring("...")

]

library LibraryName

{

importlib("stdole32.tlb");

importlib("stdole2.tlb");

typedef enum

{

valueName1 = 0,

valueName2 = 1,

...

valueNameN = N

} EnumType;

..

}

Передавать в качестве параметров структуры тоже можно. Такие структуры называются UDT - User Defined Type. В IDL описываютсятак:

Typedef [uuid(C1D3A8C0-A4AA-11D0-819C-00A0C90FFFC3)] struct UDT

{

unsigned long X;

unsigned long Y;

BSTR pbstr;

} UDT;

Описывать параметры метода можно как VARIANT но тогда придется работать с интерфесом IRecordInfo или как UDT:

Do([in]UDT* pIn, [in,out] pOut);

Передать UDT в такой метод проще простого:

UDT some_data, some_returned_data;

p->Do(&some_data, some_returned_data);

Членами UDT могут быть другие UDT или oleautomation-совместимые типы.

У вы в VC нет автоматизации позволяющей создавать пользовательские типы поэтом у все придется делать ручками

Похожие работы

  • Общая схема решения задачи на персональном компьютере

    На этапе создания текста программы вы записываете алгоритм на языке программиро-вания. Один и тот же алгоритм можно запрограммировать множеством различных спосо-бов, но вы должны стремиться написать оптимальную программу.

  • Свободная Память

    Если вы пользовались классом slist, вы могли обнаружить, что ваша программа тратит на заметное время на размещение и освобождение объектов класса slink.

  • Классы в C++

    Одной из основных черт C++, которой нет в С, является концепция классов. По существу, классы - самое важное понятие в C++. Классы похожи на структуры языка С. Однако структура С определяет только данные, ассоциированные с этой структурой.

  • Четыре секрета идеальной презентации

    Презентации для организации продаж и, в частности, PowerPoint получили заслуженно плохую репутацию в течение последних нескольких лет. Они создали и заполнили нишу мировых продаж …. продуктом, который “не вызывает аппетита”.

  • Для чего нужна процедура Sub?

    Sub это то же самое, что и Function, только она не возвращает значение, а производит какое-нибудь действие. Например вывод на экран сообщения или манипулирование несколькими свойствами.

  • Что такое API ?

    API - это сокращение от Application Programming Interface. В общем каждая программа, операционная система и т.д. имеет свой API. Windows - API состоит из целого ряда функций, которые позволяют Вам использовать системные Windows-конструкции.

  • Максимальное ускорение алгоритма поиска

    Если производится поиск DWORD-числа среди набора (массива) таких же значений, то самым оптимальным и скоростным будет последовательное сравнение заданного значения со всеми элементами массива до обнаружения совпадения.

  • Путешествуя по TObject. Или как оно работает

    Каждый класс в Delphi является наследником TObject, и, соответственно, обладает всеми его свойствами и методами. Это, несомненно, полезный факт, но каковы его методы и свойства, каковы его основные свойства и как их можно использовать?

  • Разработка алгоритма работы интеллектуальной информационной системы "Расчет меню"

    Сущность понятия "код блюда". Алгоритмы обучения и использования программы. Логика работы программы. Общий интерфейс программы. Последовательность обучения программе Lota+. Интерфейс программы в момент выбора параметров и получения общего результата.

  • Алгоритмические языки: использование множеств

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