Атрибуты и свойства в C++
От: Михаил Челноков Украина  
Дата: 11.09.02 17:30
Оценка:
Здравствуйте, уважаемые!

Как известно, в VC++ имеют место быть атрибуты и свойства.

Например, я пишу:
[ ... ]
__interface IMyInterface: IDispatch {
[propget, id(1), helpstring("property x")] HRESULT x([out, retval] INT* pX);
[propput, id(1), helpstring("property x")] HRESULT x([in] INT newX);
};

Это всё чУдно компилируется, генерится IDL, из него TLB, и потом я могу писать нечто типа
IMyInterfacePtr p;
...
p->x=0;

Однако, такое я могу писать только в другом проекте. Т.е. в том, при компиляции которого TLB уже есть и импортирован.
В том же проекте, при компиляции которого этот TLB в конце концов генерируется, компилятор выдает ошибку — нет такого поля в этом классе.

С другой стороны, можно объявить x как
__declspec(property(get=get_x,put=put_x)) INT x;
Однако это оказывается несовместимым с атрибутами [propget] и [propput]. А хочется иметь и то, и другое.

Что делать?
Re: Использование #import вместо #include
От: Vi2 Удмуртия http://www.adem.ru
Дата: 12.09.02 06:40
Оценка:
Здравствуйте Михаил Челноков, Вы писали:

МЧ>Например, я пишу:

МЧ>__interface IMyInterface: IDispatch {
МЧ>[propget, id(1), helpstring("property x")] HRESULT x([out, retval] INT* pX);
МЧ>[propput, id(1), helpstring("property x")] HRESULT x([in] INT newX);
МЧ>};


МЧ>Это всё чУдно компилируется, генерится IDL, из него TLB, и потом я могу писать нечто типа

МЧ>IMyInterfacePtr p;
МЧ>...p->x=0;

МЧ>Однако, такое я могу писать только в другом проекте. Т.е. в том, при компиляции которого TLB уже есть и импортирован. В том же проекте, при компиляции которого этот TLB в конце концов генерируется, компилятор выдает ошибку — нет такого поля в этом классе.


МЧ>Что делать?


Если у тебя файл x.idl, то Wizard добавляет в #include несколько файлов, связанных с твоим x.idl. Это файлы x.h и x_i.c.

Никто не мешает тебе убрать #include "x.h", в котором нет Врапперов из #import, и добавить вместо этого #import с этими Врапперами. Однако, нужно учесть что директива #import может генерить другие имена для виртуальных методов из интерфейса (добавляется raw_ для методов). Это нужно учитывать при реализации их в классе.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Использование #import вместо #include
От: Михаил Челноков Украина  
Дата: 12.09.02 08:11
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>Здравствуйте Михаил Челноков, Вы писали:


МЧ>>Например, я пишу:

Vi2>
МЧ>>__interface IMyInterface: IDispatch {
МЧ>>[propget, id(1), helpstring("property x")] HRESULT x([out, retval] INT* pX);
МЧ>>[propput, id(1), helpstring("property x")] HRESULT x([in] INT newX);
МЧ>>};
Vi2>


МЧ>>Это всё чУдно компилируется, генерится IDL, из него TLB, и потом я могу писать нечто типа

МЧ>>IMyInterfacePtr p;
МЧ>>...p->x=0;

МЧ>>Однако, такое я могу писать только в другом проекте. Т.е. в том, при компиляции которого TLB уже есть и импортирован. В том же проекте, при компиляции которого этот TLB в конце концов генерируется, компилятор выдает ошибку — нет такого поля в этом классе.


МЧ>>Что делать?


Vi2>Если у тебя файл x.idl, то Wizard добавляет в #include несколько файлов, связанных с твоим x.idl. Это файлы x.h и x_i.c.


Увы. У меня как раз не x.idl, а x.h, из которого компилятор генерирует _x.idl (с помощью упомянутых атрибутов) и _x.h.
В том-то все и дело — получается что idl и tlb генерируемые и мне нечему делать #import на этапе компиляции этого же проекта. Я хочу как-то заставить компилятор понять, что x — это свойство.
Re[3]: Использование #import вместо #include
От: Vi2 Удмуртия http://www.adem.ru
Дата: 12.09.02 08:16
Оценка:
Здравствуйте Михаил Челноков, Вы писали:

МЧ>Увы. У меня как раз не x.idl, а x.h, из которого компилятор генерирует _x.idl (с помощью упомянутых атрибутов) и _x.h.

МЧ>В том-то все и дело — получается что idl и tlb генерируемые и мне нечему делать #import на этапе компиляции этого же проекта. Я хочу как-то заставить компилятор понять, что x — это свойство.

В первый раз слышу о таком: из h делать idl. Наверное, у тебя что-то типа C# (до-диеза) или подобного.
Тогда нужно перекинуть из СОМ-а. Задай, куда перебросить.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: Использование #import вместо #include
От: Dima2  
Дата: 12.09.02 08:19
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>Здравствуйте Михаил Челноков, Вы писали:


МЧ>>Увы. У меня как раз не x.idl, а x.h, из которого компилятор генерирует _x.idl (с помощью упомянутых атрибутов) и _x.h.

МЧ>>В том-то все и дело — получается что idl и tlb генерируемые и мне нечему делать #import на этапе компиляции этого же проекта. Я хочу как-то заставить компилятор понять, что x — это свойство.

Vi2>В первый раз слышу о таком: из h делать idl. Наверное, у тебя что-то типа C# (до-диеза) или подобного.


Не это VC7.
Re: Атрибуты и свойства в C++
От: Torero2002 Россия  
Дата: 12.09.02 08:26
Оценка: 10 (1)
Здравствуйте Михаил Челноков, Вы писали:

МЧ>Здравствуйте, уважаемые!


МЧ>Как известно, в VC++ имеют место быть атрибуты и свойства.


МЧ>Например, я пишу:

МЧ>[ ... ]
МЧ>__interface IMyInterface: IDispatch {
МЧ>[propget, id(1), helpstring("property x")] HRESULT x([out, retval] INT* pX);
МЧ>[propput, id(1), helpstring("property x")] HRESULT x([in] INT newX);
МЧ>};

МЧ>Это всё чУдно компилируется, генерится IDL, из него TLB, и потом я могу писать нечто типа

МЧ>IMyInterfacePtr p;
МЧ>...
p->>x=0;

МЧ>Однако, такое я могу писать только в другом проекте. Т.е. в том, при компиляции которого TLB уже есть и импортирован.

МЧ>В том же проекте, при компиляции которого этот TLB в конце концов генерируется, компилятор выдает ошибку — нет такого поля в этом классе.

МЧ>С другой стороны, можно объявить x как

МЧ>__declspec(property(get=get_x,put=put_x)) INT x;
МЧ>Однако это оказывается несовместимым с атрибутами [propget] и [propput]. А хочется иметь и то, и другое.

МЧ>Что делать?


Честно говоря, это довольно известная проблема. Называется самоипорт в случае атрибутов и довольно плохо раскрытая. В случае, когда используется IDL, проблем действительно никаких нет, т.к. *.tlb файл генериться до компиляции кода, но вот в случае с атрибуатми все несколько иначе. *.tlb генериться после, перед линковкой. Поэтому возможности подключить нет. Возможно есть какой-то ключ компилятору, который его заставляет так делать, но я его не знаю. Но могу предложить другой способ: при первой компиляции генерить *.tlb, а потом ее импортировать. Для этого, например, все определения интерфейсов и коклассов, ожно вынести в отдельный файл, а файлы использующие *.tlb отключить временно. А также сказать, чтобы *.tlb не удалялся перед каждой сборкой. ПОсле этого можно импорить *.tlb.
Smart? Prove it!
Re[2]: Атрибуты и свойства в C++
От: Dima2  
Дата: 12.09.02 08:40
Оценка:
Здравствуйте Torero2002, Вы писали:

T>Честно говоря, это довольно известная проблема. Называется самоипорт в случае атрибутов и довольно плохо раскрытая. В случае, когда используется IDL, проблем действительно никаких нет, т.к. *.tlb файл генериться до компиляции кода, но вот в случае с атрибуатми все несколько иначе. *.tlb генериться после, перед линковкой. Поэтому возможности подключить нет. Возможно есть какой-то ключ компилятору, который его заставляет так делать, но я его не знаю. Но могу предложить другой способ: при первой компиляции генерить *.tlb, а потом ее импортировать. Для этого, например, все определения интерфейсов и коклассов, ожно вынести в отдельный файл, а файлы использующие *.tlb отключить временно. А также сказать, чтобы *.tlb не удалялся перед каждой сборкой. ПОсле этого можно импорить *.tlb.


Ох блин самоимпорт своей же tlb в проекте с атрибутами большая бяка. Там могут появится кучи проблем. Одна из них -почему-то пропадают из tlb затем некоторые интерфейсы, более подробно описать это не могу, но человек который этим занимался сильно матюкался на атрибуты.
Re[3]: Атрибуты и свойства в C++
От: Torero2002 Россия  
Дата: 12.09.02 08:50
Оценка:
Здравствуйте Dima2, Вы писали:

D>Здравствуйте Torero2002, Вы писали:


T>>Честно говоря, это довольно известная проблема. Называется самоипорт в случае атрибутов и довольно плохо раскрытая. В случае, когда используется IDL, проблем действительно никаких нет, т.к. *.tlb файл генериться до компиляции кода, но вот в случае с атрибуатми все несколько иначе. *.tlb генериться после, перед линковкой. Поэтому возможности подключить нет. Возможно есть какой-то ключ компилятору, который его заставляет так делать, но я его не знаю. Но могу предложить другой способ: при первой компиляции генерить *.tlb, а потом ее импортировать. Для этого, например, все определения интерфейсов и коклассов, ожно вынести в отдельный файл, а файлы использующие *.tlb отключить временно. А также сказать, чтобы *.tlb не удалялся перед каждой сборкой. ПОсле этого можно импорить *.tlb.


D>Ох блин самоимпорт своей же tlb в проекте с атрибутами большая бяка. Там могут появится кучи проблем. Одна из них -почему-то пропадают из tlb затем некоторые интерфейсы, более подробно описать это не могу, но человек который этим занимался сильно матюкался на атрибуты.


Так он все-таки смог добиться генерации *.tlb перед компиляцией? Интересно каким образом?
Smart? Prove it!
Re[4]: Атрибуты и свойства в C++
От: Dima2  
Дата: 12.09.02 09:37
Оценка:
Здравствуйте Torero2002, Вы писали:

T>Так он все-таки смог добиться генерации *.tlb перед компиляцией? Интересно каким образом?


Да я думаю очень просто два раза делаеш build и все.
Re[4]: Использование #import вместо #include
От: Михаил Челноков Украина  
Дата: 12.09.02 10:33
Оценка:
Здравствуйте Vi2, Вы писали:

МЧ>>Увы. У меня как раз не x.idl, а x.h, из которого компилятор генерирует _x.idl (с помощью упомянутых атрибутов) и _x.h.

МЧ>>В том-то все и дело — получается что idl и tlb генерируемые и мне нечему делать #import на этапе компиляции этого же проекта. Я хочу как-то заставить компилятор понять, что x — это свойство.

Vi2>В первый раз слышу о таком: из h делать idl. Наверное, у тебя что-то типа C# (до-диеза) или подобного.

Vi2>Тогда нужно перекинуть из СОМ-а. Задай, куда перебросить.

Это Visual C++ 7.0 и самый что ни есть COM...
Это визард насоздавал именно такую схему (с атрибутами). И она, в-общем-то удобна. За исключением описанного ньюанса...
Кстати, получающийся в результате tlb успешно импортируется в другой проект, а там из него компилятор делает tlh и tli, в которых уже присутствуют и __declspec(property) и inlile-функции для get и put, ну и сами get_ и put_, ессно.
Если бы он, гад, умел это же делать еще на этапе копмиляции исходного .h, цены бы ему не было.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.