VB 6.3, COM на C++ и преобразование типов

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

VB 6.3, COM на C++ и преобразование типов

Сообщение AHTOXA » 30.03.2007 (Пт) 9:15

Проблема такая:
Нужен интерфейс для класса:

IPPView

class PPView : IPPView {
virtual int Init(void * pFilt);
virtual int InitIteration();
virtual int NextIteration(void * pItem);
};

Проблема в том, что в VB нет типа void. VARIANT тоже не прокатывает, так как VB не может преобразовать пользовательский тип (определен в этом же *.idl файле) к VARIANT. Посоветуйте что-нибудь.
Bandit

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 30.03.2007 (Пт) 9:44

Раз.

tag_warning


AHTOXA, прочитай внимательно описание раздела. Не "если вы считаете, что вопрос для опытных программистов", а "если вы опытный программист".

Этот же вопрос показывает, что надо в детский сад. Первое предупреждение.
void - процедура, не возвращающая значения. В VB это SUB.
А void* (ты, похоже, даже не понимаешь отличия между void и void*) - указатель на что угодно, в VB any. и VB прекрасно понимает void* в tlb, показывая его как as any. Если по каким-то причинам это не устраивает, объявляется as long и передаётся численное значение указателя.

ЗЫ. "VB 6.3" не существует.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 30.03.2007 (Пт) 10:28

Естественно разницу между void и void * я знаю и понимаю.
1. Я опытный C++ программист, а не VB программист, который я и не считаю за язык программирования (:)).
2. Октрываем Microsoft Excel 2002, в нем встроенный VB (VBA так сильно отличается от VB?) версии 6.3, который не поддерживает "any" и указатели.
3. В idl нельзя прописать указатель на void (при компиляции MIDL выдает ошибку).
4. Можно прописать как параметр типа VARIANT, или указатель на VARIANT, но данная версия VB не поддерживает преобразование пользовательской структуры, определенной в библиотеке типов к VARIANT.
5. Понятно, что с VB.NET проблем бы скорее всего не было.
Bandit

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 30.03.2007 (Пт) 10:35

VB и VBA - совершенно разные вещи.

Как можно преобразовать объектную переменную в Variant? Как преобразуешь строку "123z" в число, интересно?

Используй VB6, а не VBA в поставке Office...

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 30.03.2007 (Пт) 10:40

1. Тогда нефиг сюда ходить.
2. any поддерживается только в tlb и в declare. Указатели поддерживаются ручками и CopyMemory. VBA отличается от VB, 6.3 - версия VBA, а не VB.
3. Какую же?
4. Значит ты сделал что-то коряво; коэрсинг структур, нормально описанных в tlb, поддерживается. Другое дело, что с какой стати туда надо писать variant, если там, извините, void*? Либо void*, либо сразу указатель на struct, ели там может быть только один тип структуры.
5. Их и так нет, но из всего сказанного пока даже не ясно, в чём именно они состоят.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 30.03.2007 (Пт) 10:42

Кто сказал, что VBA не поддерживает Any?
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
работает в VBA не хуже, чем в VB.

Кто сказал, что VBA не поддерживает указатели?
VarPtr, ObjPtr, StrPtr еще никто не отменял.
Лучший способ понять что-то самому — объяснить это другому.

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 30.03.2007 (Пт) 10:46

Amed
Как можно преобразовать объектную переменную в Variant? Как преобразуешь строку "123z" в число, интересно?

Строку в число - запросто, получится 123 :)

Вот, что я нарыл в help (для VBA 6.3):
The Variant data type is the data type for all variables that are not explicitly declared as some other type (using statements such as Dim, Private, Public, or Static). The Variant data type has no type-declaration character.

A Variant is a special data type that can contain any kind of data except fixed-length String data. (Variant types now support user-defined types.)

Теперь насчет фразы "Как можно преобразовать объектную переменную в Variant":
Вот как определяется VARIANT в oaidl.idl:

Код: Выделить всё
struct tagVARIANT
    {
    union
        {
        struct __tagVARIANT
            {
            VARTYPE vt;
            WORD wReserved1;
            WORD wReserved2;
            WORD wReserved3;
            union
                {
                LONGLONG llVal;
                LONG lVal;
                BYTE bVal;
                SHORT iVal;
                FLOAT fltVal;
                DOUBLE dblVal;
                VARIANT_BOOL boolVal;
                _VARIANT_BOOL bool;
                SCODE scode;
                CY cyVal;
                DATE date;
                BSTR bstrVal;
                IUnknown *punkVal;
                IDispatch *pdispVal;
                SAFEARRAY *parray;
                BYTE *pbVal;
                SHORT *piVal;
                LONG *plVal;
                LONGLONG *pllVal;
                FLOAT *pfltVal;
                DOUBLE *pdblVal;
                VARIANT_BOOL *pboolVal;
                _VARIANT_BOOL *pbool;
                SCODE *pscode;
                CY *pcyVal;
                DATE *pdate;
                BSTR *pbstrVal;
                IUnknown **ppunkVal;
                IDispatch **ppdispVal;
                SAFEARRAY **pparray;
                VARIANT *pvarVal;
                PVOID byref;
                CHAR cVal;
                USHORT uiVal;
                ULONG ulVal;
                ULONGLONG ullVal;
                INT intVal;
                UINT uintVal;
                DECIMAL *pdecVal;
                CHAR *pcVal;
                USHORT *puiVal;
                ULONG *pulVal;
                ULONGLONG *pullVal;
                INT *pintVal;
                UINT *puintVal;
                struct __tagBRECORD
                    {
                    PVOID pvRecord;
                    IRecordInfo *pRecInfo;
                    }    __VARIANT_NAME_4;
                }    __VARIANT_NAME_3;
            }    __VARIANT_NAME_2;
        DECIMAL decVal;
        }    __VARIANT_NAME_1;
struct tagVARIANT 
   {
    union
       {
       struct __tagVARIANT
       {
          VARTYPE vt;
          WORD wReserved1;
          WORD wReserved2;
          WORD wReserved3;
   union {
      LONGLONG                llval;             // VT_I8.
      LONG                    lVal;              // VT_I4.
      BYTE                    bVal;              // VT_UI1.
      SHORT                   iVal;              // VT_I2.
      FLOAT                   fltVal;            // VT_R4.
      DOUBLE                  dblVal;            // VT_R8.
      VARIANT_BOOL            boolVal;           // VT_BOOL.
      _VARIANT_BOOL           bool;
      SCODE                   scode;             // VT_ERROR.
      CY                      cyVal;             // VT_CY.
      DATE                    date;              // VT_DATE.
      BSTR                    bstrVal;           // VT_BSTR.
      IUnknown                * punkVal;         // VT_UNKNOWN.
      IDispatch               * pdispVal;        // VT_DISPATCH.
      SAFEARRAY               * parray;          // VT_ARRAY|*.
      BYTE                    * pbVal;           // VT_BYREF|VT_UI1.
      SHORT                   * piVal;           // VT_BYREF|VT_I2.
      LONG                    * plVal;           // VT_BYREF|VT_I4.
      LONGLONG                * pllVal;          // VT_BYREF|VT_I8.
      FLOAT                   * pfltVal;         // VT_BYREF|VT_R4.
      DOUBLE                  * pdblVal;         // VT_BYREF|VT_R8.
      VARIANT_BOOL            * pboolVal;        // VT_BYREF|VT_BOOL.
      _VARIANT_BOOL           * pbool;
      SCODE                   * pscode;          // VT_BYREF|VT_ERROR.
      CY                      * pcyVal;          // VT_BYREF|VT_CY.
      DATE                    * pdate;           // VT_BYREF|VT_DATE.
      BSTR                    * pbstrVal;        // VT_BYREF|VT_BSTR.
      IUnknown                ** ppunkVal;       // VT_BYREF|VT_UNKNOWN.
      IDispatch               ** ppdispVal;      // VT_BYREF|VT_DISPATCH.
      SAFEARRAY               ** pparray;        // VT_ARRAY|*.
      VARIANT                 * pvarVal;         // VT_BYREF|VT_VARIANT.
      PVOID                   * byref;           // Generic ByRef.
      CHAR                    cVal;              // VT_I1.
      USHORT                  uiVal;             // VT_UI2.
      ULONG                   ulVal;             // VT_UI4.
      ULONGLONG               ullVal;            // VT_UI8.
      INT                     intVal;            // VT_INT.
      UINT                    uintVal;           // VT_UINT.
      DECIMAL                 * pdecVal          // VT_BYREF|VT_DECIMAL.
      CHAR                    * pcVal;           // VT_BYREF|VT_I1.
      USHORT                  * puiVal;          // VT_BYREF|VT_UI2.
      ULONG                   * pulVal;          // VT_BYREF|VT_UI4.
      ULONGLONG               * pullVal;         // VT_BYREF|VT_UI8.
      INT                     * pintVal;         // VT_BYREF|VT_INT.
      UINT                    * puintVal;        // VT_BYREF|VT_UINT.
      struct __tagBRECORD
      {
      PVOID                   pvRecord;
      IRecordInfo             *pRecInfo;
      }    __VARIANT_NAME_4;
   }    __VARIANT_NAME_3;
  }    __VARIANT_NAME_2;
  DECIMAL decVal;
}    __VARIANT_NAME_1;

   };
};


Т.е. в принципе, преобразование любого объекта или структуры к VARIANT возможно.
Bandit

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 30.03.2007 (Пт) 10:59

А вот обратное преобразование после этого не покатит:
"123" != "123z"

А вот насчет преобразования в Variant я несколько неправ.
The Variant data type is the data type for all variables that are not explicitly declared as some other type

В Variant помещается задекларенный тип и объект.

Покажи код :)
Последний раз редактировалось Amed 30.03.2007 (Пт) 11:07, всего редактировалось 1 раз.

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 30.03.2007 (Пт) 11:02

GSerg
type of the parameter cannot derive from void or void *, вот такая ошибка
Bandit

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 30.03.2007 (Пт) 11:07

Antonariy
Спасибо, этого ответа я и ждал, попробую сейчас.
Bandit

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 30.03.2007 (Пт) 11:14

Я лично писал void* в параметрах функций интерфейса в tlb.

Код: Выделить всё
[uuid("bla_bla_bla"), object, odl]
  interface bla_bla_bla : IUnknown
  {
    ...
    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
    ...
  };


Каким именно компилятором ты пользуешься?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 30.03.2007 (Пт) 11:15

Amed
Код: Выделить всё
                Dim v_c As Lib_Test.TestView
                Dim filt As Lib_Test.TestFilt
                Set v_c = new Lib_Test.TestView
                If IsValidObj(v_c) Then
                    OK = v_c.Init(filt)
                End If
Bandit

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 30.03.2007 (Пт) 11:22

GSerg
MIDL из поставки VS.NET (VS 7.0), версии 6.00.0361
Последний раз редактировалось AHTOXA 30.03.2007 (Пт) 11:28, всего редактировалось 1 раз.
Bandit

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 30.03.2007 (Пт) 11:26

Компилируй либо через MkTypLib, либо через midl с ключом, задающим совместимость с MkTypLib. А также пометь как object и odl.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 30.03.2007 (Пт) 11:30

GSerg
OK, попробую так, спасибо. Вечером сегодня отпишусь что вышло
Bandit

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 30.03.2007 (Пт) 11:39

Имхо
Код: Выделить всё
Dim v_c As Lib_Test.TestView
Dim filt As Lib_Test.TestFilt
Set v_c = new Lib_Test.TestView
If IsValidObj(v_c) Then
    OK = v_c.Init(ObjPtr(filt))
End If

AHTOXA
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 147
Зарегистрирован: 17.04.2003 (Чт) 13:38
Откуда: Россия, г. Петрозаводск

Сообщение AHTOXA » 30.03.2007 (Пт) 11:43

Amed
Так я тоже пробовал, не выходит
Bandit


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 65

    TopList  
cron