OLE Automation Dependency #5
Replies: 4 comments 5 replies
-
|
So as I understand it we have 3 Options:
If I understood that correctly, I would tend towards option 1, but I might very well have misunderstood something 😅 |
Beta Was this translation helpful? Give feedback.
-
|
As the |
Beta Was this translation helpful? Give feedback.
-
|
Option 4 Write a little bit of code to invoke query interface on the key manually with iid_iunknown This could be implemented as a method of the dictionary class with a vtable swap and written in assembly for performance -it's a very simple method. The iid_iunknown data could be a static variable so only calculated once. Alternatively calling the query interface with dispcallfunc, although I guess that would be less performant since it requires passing arguments as variant arrays, but you would have to test |
Beta Was this translation helpful? Give feedback.
-
|
Alternative I think since VBA can execute non-compiling code provided you don't enter that procedure, you could add an error in class_initialize the first time |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Recently, there were 2 issues raised regarding
IUnknownnot being defined. See #3 and #4The
IUnknowninterface definition is part ofOLE Automation(stdole2.tlb). Although theOLE Automationreference should be on by default, this does not seem to always be the case for Mac users. The easy fix was to ask the users to add the needed reference.Should we continue using
IUnknown?It is currently used in 2 separate places in this repo:
IEnumVariantbutIEnumVariantis not present in the MacOLE AutomationsoIUnknownis used insteadvbObjectorvbDataObjectvar type. This is to enforce an object instance to be hashed to the same value regardless of what interface of that instance is being used. See hereFor the return type of
NewEnum, we can simply replace withVariantand everything will continue to work fine.However, getting a common interface for any object instance is more problematic. For example, let's assume we have a
Class1whichImplements Class2:will print something like:
which would lead to 2 different hash values, and we definitely do not want that.
Scripting.Dictionary.HashValreturns same hash value for both interfaces.The current approach of asking for the
IUnknowninterface and only then callingObjPtrwill return the same pointer regardless of what the initial interface was.The problem in VBA is that we do not have such a common interface like
IUnknowndefined in theVBAlibrary itself. We haveObjectbut that is basicallyIDispatch. As explained here, whenever we ask for theObjectinterface, a call toIDispatch::QueryInterfaceis made only if the interface being queried is not derived fromIDispatch(i.e. it's derived fromIUnknown).What is the alternative?
As explained at the end of the above Stack Overflow answer, we can use the
VBEGlobalinterface which is only derived fromIUnknownto force aQueryInterfacecall:This completely removes the need for having
OLE Automation'sIUnknowninterface but introduces the following 2 problems:Set iUnk = Keyassignment, we now need an extra pointer memory accessor. This is not really a big deal as one is already available for hashing numbers on x64 and it's easy to update the code to reuse it for the purpose of forcing aQueryInterfacecallIDispatch? We would simply not be able to assign to a variable of typeObjectwithout raising an error. A quick example:The error is raised because
[_NewEnum](IEnumVariant) is not derived fromIDispatchThe only way I can think of, to avoid this problem, is to use error handling but this will greatly impact performance when it comes to hashing keys of object type.
Goal of this discussion
It would be very helpful to see other's opinion on this and if it's worth removing the
OLE Automationdependency or to just simply add a note in the main Readme to ask users to make sure the reference is on.Thanks!
Beta Was this translation helpful? Give feedback.
All reactions