1

この問題は、Kenny Kerr による「Excel RTD サーバー: C# インターフェイス」に関するブログ投稿に関連しています。これは、特定の Excel タイプ ライブラリへの参照を含めずに Excel RTD サーバーを構築できるようにする必要があります参照を含める必要があると、RTD サーバーの Excel のバージョンが特定されます (前方互換性がありますが、後方互換性はないと思います)。Excel タイプ ライブラリに依存しないため、異なるバージョンの Excel (XP、2003、2007、および 2010) を搭載したコンピューターへの RTD の展開が簡素化されます。

ここで、インターフェイス IRtdServer および IRTDUpdateEvent を取得するために RTD が特定の Excel タイプ ライブラリを参照しないようにすることは非常に便利です。しかし、私はケニーの提案を機能させるのに非常に苦労しています。

これが私がやったことです:

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.

Excel から RTD への呼び出しをエミュレートすることで、MyRTD.dll RTD サーバーをテストする VBA と VBScript の小さなテスト ハーネスがあります。関連するコードのスニペットは次のとおりです。

最初の 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 を実装しますが。

2 番目の 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
4

1 に答える 1

1

これについてさらに作業を行い、Kenny Kerr といくつかの電子メールを交換した後、問題が発生したことが明らかになりました。同じ GUID を持ち、ComImport を使用するインターフェイスは、定義されていても、異なるアセンブリで定義されている場合、同じものとして扱われないためです。同様に。

まったく同じコード ベースを共有するインプロセス (DLL) とアウトプロセス (EXE) の両方のリアルタイム データ (RTD) サーバーがあります。つまり、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# クライアントで動作します。

于 2010-10-22T07:21:13.077 に答える