Microsoft KB Archive/327116

= InterOp interfaces must match Vtable layout for early binding to work =

Article ID: 327116

Article Last Modified on 2/12/2007

-

APPLIES TO


 * Microsoft Visual Studio 2005 Standard Edition
 * Microsoft Visual Studio 2005 Professional Edition
 * Microsoft Visual Studio .NET 2003 Professional Edition
 * Microsoft Visual Studio .NET 2003 Enterprise Architect
 * Microsoft Visual Studio .NET 2003 Enterprise Developer
 * Microsoft Visual Studio .NET 2002 Professional Edition
 * Microsoft Visual Studio .NET 2002 Enterprise Architect
 * Microsoft Visual Studio .NET 2002 Enterprise Developer
 * Microsoft Visual Basic 2005 Express Edition
 * Microsoft Visual Basic .NET 2003 Standard Edition
 * Microsoft Visual Basic .NET 2002 Standard Edition

-



This article was previously published under Q327116



SYMPTOMS
When you call a COM method through InterOp, you may receive the following error message:

An unhandled exception of type System.Exception occurred in .exe

Additional information: Object reference not set to an instance of an object.



CAUSE
This problem may occur when the order of the methods declaration in the InterOp interface does not match the order of the Vtable layout of the COM interface (which is determined by their layout in IDL). Because you perform early binding in most cases, the order of the methods is very important in this scenario.



RESOLUTION
Change the order of the methods declaration in the InterOp interface to verify that it matches the Vtable layout of the COM interface that you want to use.



STATUS
This behavior is by design.



Steps to Reproduce the Behavior
To reproduce the problem, follow these steps:

NOTE: The IOleCommandTarget interface appears in this example.  Create a Visual Basic 2005 or Visual Basic .NET Windows Application. By default, Form1 is added. Add the following references to the project:  Microsoft Internet Control (shdocvw.dll) Microsoft HTML Object Library (mshtml.tlb) </li> Add a Button control and a Web Browser control to Form1. (Click to select the Microsoft Web Browser item in the Customize ToolBox window.)

Note In Visual Studio 2005, click Tools, click Choose Toolbox Items, and then click to select Microsoft Web Brower on the COM Components tab.</li>  Add a Class to the project. By default, Class1.vb is added. Paste the following sample code to the class: Imports System Imports System.Runtime.InteropServices Public Class Class1 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _ Public Structure OLECMDTEXT Public cmdtextf As UInt32 Public cwActual As UInt32 Public cwBuf As UInt32 <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=100)> _ Public rgwz As Char End Structure

<StructLayout(LayoutKind.Sequential)> _ Public Structure OLECMD Public cmdID As UInt32 Public cmdf As UInt32 End Structure

' Interop definition for IOleCommandTarget. To reproduce the problem, the method order ' here does not match the Vtable layout of IOleCommandTarget interface. ' For more information about the IOleCommandTarget interface, see the MSDN.

<ComImport, Guid(&quot;b722bccb-4e68-101b-a2bc-00aa00404770&quot;), _ InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _ Public Interface IOleCommandTarget

Sub Exec(ByRef pguidCmdGroup As Guid, _       ByVal nCmdId As UInt32, ByVal nCmdExecOpt As UInt32, _        ByRef pvaIn As Object, ByRef pvaOut As Object) Sub QueryStatus(ByRef pguidCmdGroup As Guid, _       ByVal cCmds As UInt32, <MarshalAs(UnmanagedType.LPArray, _ SizeParamIndex:=1)> ByVal prgCmds As OLECMD, ByRef pCmdText As OLECMDTEXT) End Interface

End Class </li>  Open the Code View of the Form1.vb file, and then paste the following sample code after the Windows Form Designer generated code section of the class Form1: Private cmdGUID As New Guid(&HED016940, -17061, _   &H11CF, &HBA, &H4E, &H0, &HC0, &H4F, &HD7, &H8, &H16)

Private Enum MiscCommandTarget ViewSource = 2 End Enum

Private Sub Button1_Click(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles Button1.Click Dim cmdt As IOleCommandTarget Dim o As Object

Try cmdt = CType(GetDocument, IOleCommandTarget) cmdt.Exec(cmdGUID, Convert.ToUInt32(MiscCommandTarget.ViewSource), _           Convert.ToUInt32(SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER), o, o)        Catch Throw (New Exception(Err.GetException.Message)) End Try End Sub

Private Function GetDocument As mshtml.HTMLDocument Try Dim htm As mshtml.HTMLDocument = AxWebBrowser1.Document GetDocument = htm Catch Throw (New Exception(&quot;Cannot retrieve document from WebBrowser&quot; + _ &quot;Control: &quot; + Err.GetException.Message)) End Try End Function

Private Sub Form1_Load(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles MyBase.Load AxWebBrowser1.Navigate(&quot;http://www.microsoft.com&quot;)

End Sub

</li> Run the application. When the page appears, click the Button.</li></ol>

RESOLUTION
To resolve this problem, change the order of the method definitions in interface IOleCommandTarget, as in the following example: <ComImport, Guid(&quot;b722bccb-4e68-101b-a2bc-00aa00404770&quot;), _ InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _ Public Interface IOleCommandTarget

Sub QueryStatus(ByRef pguidCmdGroup As Guid, _       ByVal cCmds As UInt32, <MarshalAs(UnmanagedType.LPArray, _ SizeParamIndex:=1)> ByVal prgCmds As OLECMD, _       ByRef pCmdText As OLECMDTEXT) Sub Exec(ByRef pguidCmdGroup As Guid, _       ByVal nCmdId As UInt32, ByVal nCmdExecOpt As UInt32, _        ByRef pvaIn As Object, ByRef pvaOut As Object) End Interface

Keywords: kberrmsg kbprb kbpending kbcominterop kbvs2005applies kbvs2005swept KB327116

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.