Намеренные переопределения типов в IDL не проходят
От: GSerg  
Дата: 21.01.06 12:18
Оценка:
Здравствуйте.

Есть у меня задача написать большую dll с COM-классами на ATL для использования её в VB6 (иные варианты не рассматриваются, даже не предлагайте ).
Никогда этим ранее не занимался.

Начал с того, что создал в VS проект Windows DLL, добавил туда idl-файл и попробовал немного написать этот idl. На пробу, как первый шаг к дальнейшей работе. В первых строках данного файла примерно такое:
//VB-совместимость
typedef long   DWORD;
typedef DWORD *LPDWORD;
typedef DWORD *PDWORD;
typedef short  WORD;
typedef long   UINT;
typedef long   HWND;
typedef byte   CHAR;
typedef byte   UCHAR;
typedef wchar_t *PCWSTR;
typedef short  WCHAR;
typedef long   HDC;
typedef long   HMONITOR;
typedef long   HMODULE;
typedef long   HANDLE;
typedef void*  LPCVOID;

Далее идут всякие struct и interface (до фигища).
Разумеется, импорт виндовских типов MIDL делает сам из wtypes.idl, и мои переопределения идут после этого импорта.
Так вот, всё это прекрасно компилируется в tlb, и эта tlb прекрасно видится из VB6. Описал один coclass на пробу — создаётся, и методы вызываются.

Возрадовавшись, начал собственно основное — библу на ATL. Тут же оказалось, что все эти переопределения типов вызывают ошибку компиляции idl, а галка "MkTypLib Compatible", стоявшая в первом проекте, вообще не работает, ибо вызывает конфликт переопределения LIBID для самой library.

Долго сравнивал настройки проектов Windows dll и ATL (в основном, секцию MIDL). Чесал репу, но так ничего и не понял.
MSDN, опять же, но с тем же результатом.

Вот хочу спросить, как добиться от проекта ATL того же результата, как от WinDll. Чтобы работали мои переопределения.
Re: Намеренные переопределения типов в IDL не проходят
От: Аноним  
Дата: 22.01.06 23:10
Оценка:
Здравствуйте, GSerg, Вы писали:

GS>Здравствуйте.


GS>Есть у меня задача написать большую dll с COM-классами на ATL для использования её в VB6 (иные варианты не рассматриваются, даже не предлагайте ).

GS>Никогда этим ранее не занимался.

GS>Начал с того, что создал в VS проект Windows DLL, добавил туда idl-файл и попробовал немного написать этот idl. На пробу, как первый шаг к дальнейшей работе. В первых строках данного файла примерно такое:

GS>
GS>//VB-совместимость
GS>typedef long   DWORD;
GS>typedef DWORD *LPDWORD;
GS>typedef DWORD *PDWORD;
GS>typedef short  WORD;
GS>typedef long   UINT;
GS>typedef long   HWND;
GS>typedef byte   CHAR;
GS>typedef byte   UCHAR;
GS>typedef wchar_t *PCWSTR;
GS>typedef short  WCHAR;
GS>typedef long   HDC;
GS>typedef long   HMONITOR;
GS>typedef long   HMODULE;
GS>typedef long   HANDLE;
GS>typedef void*  LPCVOID;
GS>

GS>Далее идут всякие struct и interface (до фигища).
GS>Разумеется, импорт виндовских типов MIDL делает сам из wtypes.idl, и мои переопределения идут после этого импорта.
GS>Так вот, всё это прекрасно компилируется в tlb, и эта tlb прекрасно видится из VB6. Описал один coclass на пробу — создаётся, и методы вызываются.

Подход не верен в принципе. VB6 нужны IDispatch интерфейсы, и ваши структуры и т.п. работать не будут. Кроме того, не будет работать typelibrary маршаллинг. Пакуйте структуры в интерфейсы и используйте только Automation types.
Re[2]: Намеренные переопределения типов в IDL не проходят
От: GSerg  
Дата: 23.01.06 02:29
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Подход не верен в принципе

Тогда не получилось бы создать VB-compatible tlb в проекте Windll.

А>VB6 нужны IDispatch интерфейсы

В корне неверное представление закоренелого сишника
VB отлично работает с IUnknown без дополнительных телодвижений, а с одним дополнительным телодвижением работает ещё и с не-IUnknown.

А>и ваши структуры и т.п. работать не будут.

Увы, они уже работают. Из проекта WinDLL

А>Кроме того, не будет работать typelibrary маршаллинг.

Увы, работает и он

А>Пакуйте структуры в интерфейсы и используйте только Automation types.

Так вот только для введения Automation types всё и затевается.
Если VB увидит в tlb тип unsigned long, он скажет: <unsupported automation type>. Поэтому, когда мы из VB ведём диалог с сишными прогами, ожидающими ULONG, мы передаём наш обычный LONG, просто помним, что на самом деле он U.

И под структурами я подразумевал пользовательские типы. Контсрукцию struct из tlb VB трактует как свой Type (и правильно делает). У меня нет намерения использовать struct в качестве замены интерфейсу. Интерфейсы — они отдельно.


Понимаете, я могу во всей tlb руками разменить все ULONG на long и т.д. Но я не хочу этого делать, т.к. знаю, что можно через typedef. Я понимаю, что с точки зрения сишников подход может казаться странным, но тем не менее всё годами работает именно так.

Поэтому повторю первоначальный вопрос — как заставить typedef работать в проекте ATL так же, как он работает в WinDLL?
Re: Намеренные переопределения типов в IDL не проходят
От: Vi2 Удмуртия http://www.adem.ru
Дата: 23.01.06 05:57
Оценка:
Здравствуйте, GSerg, Вы писали:

GS>Долго сравнивал настройки проектов Windows dll и ATL (в основном, секцию MIDL). Чесал репу, но так ничего и не понял.

GS>MSDN, опять же, но с тем же результатом.

Потому что генерируемые здесь (т.е. для Windows dll) файлы (всякие там h и c) не используются в создании рабочего кода и фактически не обрабатываются компилятором С++, т.к. используется только генерируемая TLB как описание функций Windows.

GS>Вот хочу спросить, как добиться от проекта ATL того же результата, как от WinDll. Чтобы работали мои переопределения.


Обычно такие замены в IDL обрамляются в скобки с тем, чтобы реально использовались реальные типы (из windows.h), а не их подмены в TLB:
cpp_quote("#if 0")

typedef long   DWORD;
...

cpp_quote ("#endif")
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Намеренные переопределения типов в IDL не проходят
От: Аноним  
Дата: 24.01.06 05:06
Оценка:
Спорить не буду — лень. Дело ваше — положите кучу усилий, а потом ничего работать не будет. Вы где-нибудь видели такой подход к написанию компонентов для VB? A почему никто и никогда так не делает?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.