COM RTD-сервер Excel - Невозможно привести UpdateEvent (класс) к IRTDUpdateEvent (интерфейс) - PullRequest
1 голос
/ 17 октября 2010

Эта проблема связана с сообщением Кенни Керра в блоге «Серверы RTD Excel: интерфейсы C #», которое можно найти здесь , которое должно позволить вам создать сервер RTD Excel без включения ссылки в любую конкретную библиотеку типов Excel; включение ссылки делает конкретную версию вашего RTD-сервера Excel (вернее, совместимой, но не обратно-совместимой, я считаю). Отсутствие зависимости от библиотеки типов Excel упрощает развертывание RTD на компьютерах с различными версиями Excel (XP, 2003, 2007 и 2010).

Теперь не иметь RTD-ссылки на конкретную библиотеку типов Excel для получения интерфейсов IRtdServer и IRTDUpdateEvent - это очень хорошо. Но у меня дьявольское время заставляет работать предложение Кенни.

Вот что я сделал:

1) Added IRtdServer.cs and IRTDUpdateEvent.cs to my RTD project and put the interface definitions from your blog into those files (not changing the GUIDs).
2) Removed any reference to an Excel type library.
3) Build and regasm OK.

У меня есть небольшие тестовые наборы в VBA и VBScript, которые тестируют мой RTD-сервер MyRTD.dll, эмулируя вызовы, сделанные Excel к RTD. Вот соответствующие фрагменты кода:

Первый VBA:

Const RTDProgID As String = "MyRTD.RTD"
Const UpdateEventProgID As String = "MyRTD.UpdateEvent"

' Create the RTD server object.
Dim rtd As Object
Set rtd = CreateObject(RTDProgID)

' Start the RTD server, passing in a callback object.
Dim callback As Object
Set callback = CreateObject(UpdateEventProgID)
Dim status As Long
status = rtd.ServerStart(callback)    <----    Fails here.

Этот код завершается с ошибкой в ​​последней строке с сообщением вдоль строк «Не удается преобразовать MyRTD.UpdateEvent в MyRTD.IRTDUpdateEvent». Хотя класс UpdateEvent реализует интерфейс IRTDUpdateEvent.

Второй VBScript:

' ProgIDs for COM components.
Const RTDProgID = "MyRTD.RTD"
Const UpdateEventProgID = "MyRTD.UpdateEvent"

' Real-time data (RTD) object
Dim rtd
Set rtd = CreateObject(rtdID)

' Callback object. This is how
' the RTD would notify Excel of
' new data updates.
Dim callback
Set callback = CreateObject(UpdateEventProgID)

' Start the RTD server, passing in
' the callback object.
Dim status
status = rtd.ServerStart(callback)    <----    Fails here.

Этот код завершается с ошибкой в ​​последней строке с сообщением вдоль строк «Недопустимый вызов процедуры или аргумент» (что, как я полагаю, является результатом обратного вызова неправильного типа / интерфейса).

Любая помощь будет оценена.

             Best regards, Andrew Sheppard

1 Ответ

1 голос
/ 22 октября 2010

После некоторой дополнительной работы над этим и обмена некоторыми электронными письмами с Кенни Керром стало ясно, что проблема возникла, потому что интерфейсы с одинаковым GUID и использованием ComImport не рассматриваются как одно и то же, если они определены в разных сборках даже если определены одинаково.

У меня есть сервер данных в реальном времени (RTD) как в процессе (DLL), так и вне процесса (EXE), который использует одну и ту же базу кода; то есть тот же RTD, другая модель исполнения. Я взял IRTDUpdateEvent и поместил его в отдельную сборку. IRTDUpdateEvent, конечно, реализован библиотекой объектов Excel; но я определяю это сам, поэтому мне не нужно заставлять свой RTD зависеть от конкретной версии Excel (2002, 2003, 2007, 2010), что упрощает развертывание.

Это не было бы проблемой, если бы я использовал C # 4.0 из-за новой функции "эквивалентности типов". Вы можете заставить классы / интерфейсы с одинаковым GUID вести себя так, как если бы они были одинаковыми (что имеет больше смысла), независимо от того, где они определены. Но моя целевая платформа - версии до 4.0.

Исправление было в том, чтобы переместить IRTDUpdateEvent из его собственной сборки обратно в сборки DLL и EXE. После этого серверы DLL и EXE RTD работают с клиентами Excel и VBA, а также с VBScript и C #.

...