Как известно, в 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, и потом я могу писать нечто типа МЧ>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_ для методов). Это нужно учитывать при реализации их в классе.
МЧ>>Это всё чУдно компилируется, генерится 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 — это свойство.
Здравствуйте Михаил Челноков, Вы писали:
МЧ>Увы. У меня как раз не x.idl, а x.h, из которого компилятор генерирует _x.idl (с помощью упомянутых атрибутов) и _x.h. МЧ>В том-то все и дело — получается что idl и tlb генерируемые и мне нечему делать #import на этапе компиляции этого же проекта. Я хочу как-то заставить компилятор понять, что x — это свойство.
В первый раз слышу о таком: из h делать idl. Наверное, у тебя что-то типа C# (до-диеза) или подобного.
Тогда нужно перекинуть из СОМ-а. Задай, куда перебросить.
Здравствуйте Vi2, Вы писали:
Vi2>Здравствуйте Михаил Челноков, Вы писали:
МЧ>>Увы. У меня как раз не x.idl, а x.h, из которого компилятор генерирует _x.idl (с помощью упомянутых атрибутов) и _x.h. МЧ>>В том-то все и дело — получается что idl и tlb генерируемые и мне нечему делать #import на этапе компиляции этого же проекта. Я хочу как-то заставить компилятор понять, что x — это свойство.
Vi2>В первый раз слышу о таком: из h делать idl. Наверное, у тебя что-то типа C# (до-диеза) или подобного.
Здравствуйте Михаил Челноков, Вы писали:
МЧ>Здравствуйте, уважаемые!
МЧ>Как известно, в 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.
Здравствуйте Torero2002, Вы писали:
T>Честно говоря, это довольно известная проблема. Называется самоипорт в случае атрибутов и довольно плохо раскрытая. В случае, когда используется IDL, проблем действительно никаких нет, т.к. *.tlb файл генериться до компиляции кода, но вот в случае с атрибуатми все несколько иначе. *.tlb генериться после, перед линковкой. Поэтому возможности подключить нет. Возможно есть какой-то ключ компилятору, который его заставляет так делать, но я его не знаю. Но могу предложить другой способ: при первой компиляции генерить *.tlb, а потом ее импортировать. Для этого, например, все определения интерфейсов и коклассов, ожно вынести в отдельный файл, а файлы использующие *.tlb отключить временно. А также сказать, чтобы *.tlb не удалялся перед каждой сборкой. ПОсле этого можно импорить *.tlb.
Ох блин самоимпорт своей же tlb в проекте с атрибутами большая бяка. Там могут появится кучи проблем. Одна из них -почему-то пропадают из tlb затем некоторые интерфейсы, более подробно описать это не могу, но человек который этим занимался сильно матюкался на атрибуты.
Здравствуйте Dima2, Вы писали:
D>Здравствуйте Torero2002, Вы писали:
T>>Честно говоря, это довольно известная проблема. Называется самоипорт в случае атрибутов и довольно плохо раскрытая. В случае, когда используется IDL, проблем действительно никаких нет, т.к. *.tlb файл генериться до компиляции кода, но вот в случае с атрибуатми все несколько иначе. *.tlb генериться после, перед линковкой. Поэтому возможности подключить нет. Возможно есть какой-то ключ компилятору, который его заставляет так делать, но я его не знаю. Но могу предложить другой способ: при первой компиляции генерить *.tlb, а потом ее импортировать. Для этого, например, все определения интерфейсов и коклассов, ожно вынести в отдельный файл, а файлы использующие *.tlb отключить временно. А также сказать, чтобы *.tlb не удалялся перед каждой сборкой. ПОсле этого можно импорить *.tlb.
D>Ох блин самоимпорт своей же tlb в проекте с атрибутами большая бяка. Там могут появится кучи проблем. Одна из них -почему-то пропадают из tlb затем некоторые интерфейсы, более подробно описать это не могу, но человек который этим занимался сильно матюкался на атрибуты.
Так он все-таки смог добиться генерации *.tlb перед компиляцией? Интересно каким образом?
Здравствуйте 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, цены бы ему не было.