クライアント VB アプリケーションで使用するアウト プロセス VB COM サーバーの作成に取り組んでおり、アプリケーションに安定性をもたらします。
MSDN からのサンプル コードの次のリンクは、VB COM サーバーの作成に役立ち、その COM サーバーからメソッド、プロパティ、およびイベントを正常に公開しました。https://code.msdn.microsoft.com/windowsdesktop/VBExeCOMServer-a5b9f49f
次のコードを使用して、クライアント アプリケーションで COM サーバーを使用しました。プロパティと関数の呼び出しでは問題なく動作しましたが、COM サーバーによって公開されたイベントを処理しようとすると、コンパイル時エラーが発生します。
Dim obj = CreateObject("MeridiaAPICOMServer.BaseControllerSimple")
obj.TestProperty = "test" // worked fine
obj.TestFunction() // worked fine
AddHandler obj.TestEvent, AddressOf TestEventHandlerFunction
//コンパイル時エラー!!! TestEvent は「オブジェクト」のイベントではありません
このコンパイル時エラーを解決するために、次のコードを使用してオブジェクト型を「BaseControllerSimple」型に型キャストしようとしましたが、その変更により、実行時に例外が発生します。
Dim obj As BaseControllerSimple = CreateObject("MeridiaAPICOMServer.BaseControllerSimple")
//例外! タイプ 'System.__ComObject' の COM オブジェクトをクラス タイプ 'MeridiaAPICOMServer.BaseControllerSimple' にキャストできません。COM コンポーネントを表す型のインスタンスは、COM コンポーネントを表さない型にキャストできません。ただし、基になる COM コンポーネントがインターフェイスの IID に対する QueryInterface 呼び出しをサポートしている限り、インターフェイスにキャストできます。
その後、COM Server のコードでインターフェイスを作成してみて、そのインターフェイスを実装する「BaseControllerSimple」クラスを作成しました。インターフェイスとそれを実装するクラスのコード スニペットを次に示します。
<ComImport(), ComVisible(True), _
InterfaceType(ComInterfaceType.InterfaceIsIUnknown), _
Guid("0742da3d-1cfa-4a3d-a104-35dbecb4ea48")> _
Public Interface IBaseControllerSimple
<DispId(1)> Event TestEvent(ByVal portName As String, ByVal baseID As Long)
<DispId(2)> Sub TestFunction()
<DispId(3)> Property TestProperty() As String
End Interface
以下は、IBaseControllerSimple クラスのコードです。
<ComClass(BaseControllerSimple.ClassId, BaseControllerSimple.InterfaceId, BaseControllerSimple.EventsId), ComVisible(True)> _
Public Class BaseControllerSimple
Inherits ReferenceCountedObject
Implements IBaseControllerSimple
Public Const ClassId As String _
= "9b5a0579-4f03-4a48-8d29-79dbbdbd32a9"
Public Const InterfaceId As String _
= "0742da3d-1cfa-4a3d-a104-35dbecb4ea48"
Public Const EventsId As String _
= "496a6535-4d44-4ee2-be02-ed69938e799b"
' These routines perform the additional COM registration needed by
' the service.
<ComRegisterFunction(), EditorBrowsable(EditorBrowsableState.Never)> _
Public Shared Sub Register(ByVal t As Type)
Try
COMHelper.RegasmRegisterLocalServer(t)
Catch ex As Exception
Console.WriteLine(ex.Message) ' Log the error
Throw ex ' Re-throw the exception
End Try
End Sub
<EditorBrowsable(EditorBrowsableState.Never), ComUnregisterFunction()> _
Public Shared Sub Unregister(ByVal t As Type)
Try
COMHelper.RegasmUnregisterLocalServer(t)
Catch ex As Exception
Console.WriteLine(ex.Message) ' Log the error
Throw ex ' Re-throw the exception
End Try
End Sub
Public Sub New()
MyBase.New()
End Sub
Public Event TestEvent(ByVal portName As String, ByVal baseID As Long) _
Implements IBaseControllerSimple.TestEvent
// TestFunction and TestProperty are also implemented and defined here...
End Class
インターフェイスを定義した後、次のコードを試しました。
Dim obj As IBaseControllerSimple = CreateObject("MeridiaAPICOMServer.BaseControllerSimple")
//例外'System.__ComObject' 型の COM オブジェクトをインターフェース型 'IBaseControllerSimple' にキャストできません。IID '{0742DA3D-1CFA-4A3D-A104-35DBECB4EA48}' を持つインターフェイスの COM コンポーネントでの QueryInterface 呼び出しが次のエラーのために失敗したため、この操作は失敗しました: No such interface supported (HRESULT からの例外: 0x80004002 (E_NOINTERFACE)) .
解決策、または VB COM サーバーによって公開されるイベントの処理の問題を解決するのに役立つあらゆる種類のフィードバックを楽しみにしています。前もって感謝します。