Статья

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

Работа добавлена на сайт bukvasha.net: 2015-10-29

Поможем написать учебную работу

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

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 22.11.2024



Оформление класса в виде 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 нет автоматизации позволяющей создавать пользовательские типы поэтом у все придется делать ручками

Список литературы

Для подготовки данной работы были использованы материалы с сайта http://www.realcoding.net/



1. Реферат на тему Расстройства сознания
2. Курсовая Влияние рекламы качества и ассортимента продукции на неценовую конкуренцию
3. Диплом Влияние органических удобрений на развитие и урожайность томатов безрассадных
4. Реферат Гвиччардини, Франческо
5. Реферат Государственный режим
6. Реферат Российская революция 1905-1907г.г. причины, характер, движущие силы, итоги, отноше
7. Реферат Святые великомученницы.
8. Реферат на тему The Science Of Cosmetics Essay Research Paper
9. Курсовая на тему Беспроводные локальные сети Wlan wi fi
10. Реферат Инцидент 31 марта