Обертка для С++ класса. Нужен пример.
От: Цунцуяби Россия  
Дата: 02.10.02 09:12
Оценка:
У меня есть проект в котором имеется некоторая иерархия классов.


class Ycl
{
    int value;
public:
...
    int GetValue(void){return value;}
    void SetValue(int nv){value=nv;}
};

class Xcl
{
    Ycl *y;
...
public:
    Ycl &Item(int i){return y[i];}
};


В С++ я могу написать так



Xcl x;
x.Item(1).SetValue(10);


Мне необходима обертка (COM,ATL)
чтобы я мог также писать и в VB


x.Item(1).value=10


Не поможет ли кто с примером ?

Пробовал написать по примерам с ATL, но я пока не понимаю всю картину вцелом
и поэтому смущает, что каждый раз когда я вызываю метод Item
у меня каждый раз создается и инициализируется объект


STDMETHODIMP CComXcl::Item(short n, LPDISPATCH *retval)
{
    CComObject<CComYcl>* p = new CComObject<CComYcl>;
    p->DoNotForgetInitItem();
    IDispatch* pDisp;
    HRESULT res=p->QueryInterface(IID_IDispatch, (void**)&pDisp);
    if (res != S_OK) return E_POINTER;
    *retval = pDisp;
    return S_OK;
}


Может быть его надо где-то сохранять ?

А вообше у меня получается


o1=x.Item(1)
o2=x.Item(1)

o1.value=1
o2.value=2


o1.value != o2.value

что-то видно делаю не так, а ?
Re: Обертка для С++ класса. Нужен пример.
От: George Seryakov Россия  
Дата: 03.10.02 01:55
Оценка:
Здравствуйте Цунцуяби, Вы писали:


Ц>Пробовал написать по примерам с ATL, но я пока не понимаю всю картину вцелом

Ц>и поэтому смущает, что каждый раз когда я вызываю метод Item
Ц>у меня каждый раз создается и инициализируется объект

Ц>
Ц>STDMETHODIMP CComXcl::Item(short n, LPDISPATCH *retval)
Ц>{
Ц>    CComObject<CComYcl>* p = new CComObject<CComYcl>;
Ц>    p->DoNotForgetInitItem();
Ц>    IDispatch* pDisp;
Ц>    HRESULT res=p->QueryInterface(IID_IDispatch, (void**)&pDisp);
Ц>    if (res != S_OK) return E_POINTER;
Ц>    *retval = pDisp;
Ц>    return S_OK;
Ц>}
Ц>


Ц>Может быть его надо где-то сохранять ?


Да. В статическом члене. Типа

    // где- то в *.h, в определении класса
    static map<short, CComPtr<IDispatch> arrayItems;

STDMETHODIMP CComXcl::Item(short n, LPDISPATCH *retval)
{
...
    if(arrayItems.find(n) != arrayItems.end()) {
    CComObject<CComYcl>* p = new CComObject<CComYcl>;
    p->DoNotForgetInitItem();
    IDispatch* pDisp;
    HRESULT res=p->QueryInterface(IID_IDispatch, (void**)&pDisp);
    if (res != S_OK) { 
           return E_POINTER;
        }
       arrayItems[n] = pDisp; 
        *retval = pDisp;
        return S_OK;
    } else {
        *retval = arrayItems[n].Detach();
        return S_OK;
    }
}


Писал без компилятора, могут быть ошибки. Но где-то так.
GS
Re[2]: Обертка для С++ класса. Нужен пример.
От: George Seryakov Россия  
Дата: 03.10.02 03:15
Оценка:
Здравствуйте George Seryakov, Вы писали:

GS> Да. В статическом члене. Типа


Отставить в статическом. В обычном.

GS>[ccode]

GS> // где- то в *.h, в определении класса
GS> /*static*/ map<short, CComPtr<IDispatch> arrayItems;


GS>Писал без компилятора, могут быть ошибки. Но где-то так.


Или эдак, как обычно.
GS
Re: Метод CComXcl::Item
От: Vi2 Удмуртия http://www.adem.ru
Дата: 03.10.02 04:00
Оценка:
Здравствуйте Цунцуяби, Вы писали:

Ц>У меня есть проект в котором имеется некоторая иерархия классов.


Ц>class Ycl
Ц>{
Ц>    int value;
Ц>public:
Ц>...
Ц>    int GetValue(void){return value;}
Ц>    void SetValue(int nv){value=nv;}
Ц>};

Ц>class Xcl
Ц>{
Ц>    Ycl *y;
Ц>...
Ц>public:
Ц>    Ycl &Item(int i){return y[i];}
Ц>};


Я так понимаю, что и Xcl и Ycl имеют обёртки в СОМ. Тогда n-ый элемент у тебя уже есть, его не надо создавать заново.

Ц>Пробовал написать по примерам с ATL, но я пока не понимаю всю картину вцелом и поэтому смущает, что каждый раз когда я вызываю метод Item у меня каждый раз создается и инициализируется объект

Ц>STDMETHODIMP CComXcl::Item(short n, LPDISPATCH *retval)
Ц>{
Ц>    CComObject<CComYcl>* p = new CComObject<CComYcl>;
Ц>    p->DoNotForgetInitItem();
Ц>    IDispatch* pDisp;
Ц>    HRESULT res=p->QueryInterface(IID_IDispatch, (void**)&pDisp);
Ц>    if (res != S_OK) return E_POINTER;
Ц>    *retval = pDisp;
Ц>    return S_OK;
Ц>}


Ц>Может быть его надо где-то сохранять ?


Так он у тебя есть, его и сохранять-то не надо. Вот примерно так.
STDMETHODIMP CComXcl::Item(short n, LPDISPATCH *retval)
{
    // нужен анализ невыхода за границы массива y
    // y[n] - это объект-обёртка Ycl, значит, имеет QueryInterface
    return y[n].QueryInterface(IID_IDispatch, (void**)&pDisp);
}
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Обертка для С++ класса. Нужен пример.
От: Цунцуяби Россия  
Дата: 03.10.02 11:54
Оценка:
Здравствуйте George Seryakov, Вы писали:


GS>STDMETHODIMP CComXcl::Item(short n, LPDISPATCH *retval)

GS>{
GS>...
GS> if(arrayItems.find(n) != arrayItems.end()) {
GS> CComObject<CComYcl>* p = new CComObject<CComYcl>;
GS> p->DoNotForgetInitItem();
GS> IDispatch* pDisp;
GS> HRESULT res=p->QueryInterface(IID_IDispatch, (void**)&pDisp);
GS> if (res != S_OK) {
GS> return E_POINTER;
GS> }
GS> arrayItems[n] = pDisp;
GS> *retval = pDisp;
GS> return S_OK;
GS> } else {
GS> *retval = arrayItems[n].Detach();
GS> return S_OK;
GS> }
GS>}
GS>[/ccode]

Попробовал, получилось, спасибо.
Правда вместо arrayItems[n].Detach() использовал arrayItems[n].CopyTo(retval);
иначе при последующих обращениях -- Cannot evaluate to an object
Re[3]: Обертка для С++ класса. Нужен пример.
От: George Seryakov Россия  
Дата: 03.10.02 14:06
Оценка:
Здравствуйте Цунцуяби, Вы писали:

GS>>    CComObject<CComYcl>* p = new CComObject<CComYcl>;
GS>>    p->DoNotForgetInitItem();
GS>>    IDispatch* pDisp;
GS>>    HRESULT res=p->QueryInterface(IID_IDispatch, (void**)&pDisp);



Ц>Попробовал, получилось, спасибо.

Ц>Правда вместо arrayItems[n].Detach() использовал arrayItems[n].CopyTo(retval);
Ц>иначе при последующих обращениях -- Cannot evaluate to an object

Моя просдача. С прямым углом перепутал.

И еще — конструкция с new CComObject<> нужна только если хочешь иметь доступ к С++-методам и членам кокласса. Иначе достаточно обычного

    CComPtr<IDispatch> p;
    HRESULT res = p.CoCreateInstance(CLSID_ComYcl);
GS
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.