IDispatch Late-Binding Cache Invalidation in Visual Basic 6
0 reputation · 05 Jun 2022, 23:03 UTC
0 reputation · 05 Jun 2022, 23:03 UTC
Visual Basic 6 utilizes a runtime cache for IDispatch identifiers (DispIDs) when performing late-bound calls to COM objects. This mechanism optimizes performance by storing the mapping between a member name and its numeric ID after the initial resolution.
A challenge arises when the underlying COM component is updated or modified while an object reference remains active in the VB6 environment. Because the runtime relies on the cached DispID, changes to the component's interface—such as shifting IDs due to new method additions—can lead to inconsistencies between the cached ID and the actual component implementation.
While releasing the object reference typically clears the cache, there is no built-in mechanism to force a refresh of the DispID map without destroying the object instance.
IDispatch cache for a specific object without setting the reference to Nothing?34775 reputation · 06 Jun 2022, 07:32 UTC
The Visual Basic 6 runtime does not expose any method, API call, or setting that can invalidate the IDispatch DispID cache for a live object reference while keeping that reference alive. Likewise, there is no documented configuration (registry key, INI file, or environment variable) that disables the caching so that every late‑bound call performs a fresh name resolution.
IDispatch::GetIDsOfNames; the returned DispID is stored in an internal cache associated with that object variable.Nothing (or goes out of scope), which destroys the reference and clears the cache.The cache is an internal optimization of the VB6 dispatch helper. Because the helper holds the DispID in a per‑variable slot, the only way to obtain a new slot (and thus a fresh lookup) is to drop the old variable and create a new reference via CreateObject, GetObject, or similar.
Nothing (e.g., Set obj = Nothing).Set obj = CreateObject("ProgID.Class")).GetIDsOfNames call and cache the new DispID.' VB6 test sketch
Dim obj As Object
Set obj = CreateObject("Some.Com.Class")
' First call caches DispID for "MethodA"
obj.MethodA
' Modify the component (add/reorder a method) while obj remains alive
' Second call will likely fail with "Member not found" if the DispID shifted
' Release and recreate
Set obj = Nothing
Set obj = CreateObject("Some.Com.Class")
obj.MethodA ' succeeds after fresh lookup
If releasing the object could affect other parts of your application (e.g., the COM server is shared or uses a singleton lifetime), you should confirm whether the component is designed to tolerate multiple instances or if it relies on a single live reference. Knowing this will determine whether the release‑and‑recreate approach is safe in your specific scenario.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.