VB6 и COM: нельзя использовать параметр определяемого пользователем типа в функции COM

Я использую COM-объект в VB6. У COM-объекта есть функция Foo (Long, Long, Rect). Rect - это структура, определенная в реализации COM-объекта. Мой код VB6 (кнопка в форме) выглядит следующим образом:

Private Sub btnTestCom_Click()
    Set ComObj = CreateObject("ObjectName")
    Dim rect As DISPLAY_RECT

    rect.Left = 20
    rect.Top = 20

    ComObj.Foo(101, 0, rect) ' Error here
End Sub

В последней строке он выдает ошибку компиляции: «Только пользовательские типы, определенные в общедоступных объектных модулях, могут быть принудительно преобразованы в вариант или из него или переданы в функции с поздним связыванием».

Другие функции COM, не имеющие параметров определяемого пользователем типа, работают нормально.

Как мне решить эту проблему?

Спасибо.


person Charlie    schedule 15.08.2011    source источник
comment
Митч, что ты имеешь в виду? DISPLAY_RECT - это структура, определенная в сторонней библиотеке COM, и я имею в виду эту библиотеку.   -  person Charlie    schedule 15.08.2011
comment
Сообщение об ошибке говорит, что это не так. Как и ваш код, вам не нужно использовать CreateObject (), если вы ссылаетесь на библиотеку типов COM. Вы должны использовать DISPLAY_RECT из той же библиотеки типов, которая объявила ObjectName. Другой с таким же именем работать не может, у него будет другой guid.   -  person Hans Passant    schedule 15.08.2011
comment
@Hans имеет хорошее мнение. Проверьте, какой DISPLAY_RECT используется. Я отредактировал свой ответ, чтобы предложить один из способов сделать это (найдите DISPLAY_RECT в обозревателе объектов)   -  person MarkJ    schedule 15.08.2011
comment
Привет, @Hans, что вы имеете в виду, говоря, что вам не нужно использовать CreateObject (), если вы ссылаетесь на библиотеку типов COM? Я всегда использовал COM в VB6 следующим образом: (1) добавить ссылку на библиотеку (2) вызвать obj = CreateObject (classname) (3) вызвать obj.Foo (), obj.Bar ()   -  person Charlie    schedule 16.08.2011
comment
Значит, ты всегда делал это неправильно. Смысл добавления библиотеки типов в том, что вам не нужно использовать CreateObject (). Вы просто используете Dim obj As New Foo. Нет необходимости в библиотеке типов, если вы используете ее с поздним связыванием.   -  person Hans Passant    schedule 16.08.2011
comment
@Charlie @ Ханс Ханс прав. Позднее связывание (с использованием Dim obj As New Foo) намного лучше. Например, если вы используете позднее связывание, будет легче сделать правильный вызов этого ComObj.Foo метода. IDE будет давать вам подсказки IntelliSense о типах параметров по мере ввода, а компилятор проверяет, правильно ли вы их указали.   -  person MarkJ    schedule 16.08.2011


Ответы (2)


Вызов функции имеет позднюю привязку, поскольку ваша переменная ComObj не типизирована. Вы можете попробовать объявить это, например,

Dim ComObj As SomeObjectDefinedInComImplementation 

ИЗМЕНИТЬ

Я также хотел бы проверить, действительно ли вы используете DISPLAY_RECT из библиотеки COM. Откройте обозреватель объектов (нажмите F2) и найдите во всех библиотеках DISPLAY_RECT.

  • If you only see one result, check whether it's from the correct COM library.
    • If it's from the correct COM library, there must be another problem.
    • Если он из неправильной библиотеки COM: проверьте, действительно ли у вас есть ссылка на правильную библиотеку (в ссылках на проект). Если у вас уже есть ссылка на него, еще раз проверьте, действительно ли вы должны сдавать DISPLAY_RECT
  • Если вы видите несколько результатов, возможно, VB6 выбирает неправильную библиотеку. Попробуйте явно указать DISPLAY_RECT именем библиотеки Dim rect As TheCorrectLibraryName.DISPLAY_RECT
person MarkJ    schedule 15.08.2011
comment
Помните, что есть некоторые шансы, что он увидит только не ту. - person Hans Passant; 15.08.2011
comment
Привет, @MarkJ и Ханс, извините, я не разъяснил свою проблему. DISPLAY_RECT на самом деле XXX_DISPLAY_RECT. Так что это единственно правильный из правильной библиотеки COM. Как предположил MarkJ, должна быть другая проблема. Теперь я собираюсь попробовать решение RS Conley. Я буду держать вас в курсе, ребята. Спасибо - person Charlie; 16.08.2011
comment
@Charlie Вы сказали, что это сторонняя библиотека? В этом случае я не думаю, что ответ Р.С. Конли уместен. Библиотека ожидает определенный тип, вы должны передать правильный тип, как определено в библиотеке. Вы не можете просто создать собственный класс и вместо этого передать его. Это было бы более подходящим, если бы библиотека была вашим кодом, и вы тоже могли бы ее изменить. - person MarkJ; 16.08.2011

Предполагая, что DISPLY_RECT является типом, вы не можете передавать типы в общедоступный метод COM или возвращать тип из общедоступной функции COM в VB6. Вам нужно будет создать класс, дублирующий тип, и вспомогательную функцию, которая принимает класс в качестве параметра и возвращает тип.

person RS Conley    schedule 15.08.2011