How to pass interface type/GUID reference to an automation method in Delphi
In Delphi you can pass class references a开发者_如何学Cround to compare the types of objects, and to instantiate them. Can you do the same with interface references being passed to a COM automation server?
For example, you can define a method taking a GUID parameter using the type library editor:
function ChildNodesOfType(NodeType: TGUID): IMBNode; safecall;
In this function I would like to return automation types that support the interface specified by NodeType, e.g.
if Supports(SomeNode, NodeType) then
result := SomeNode;
But the Supports call always fails, I tried passing in the Guids defined in the type library but none of the different types (Ixxx, Class_xxxx, IId_Ixxxx) seem to work.
The SysUtils unit comes with at least five overloads of Supports
, and they all accept a TGUID
value for their second parameters.
You can indeed pass interface types as parameters, but they're really just GUIDs. That is, when a function expects a TGUID
argument, you can pass it the interface type identifier, such as IMBNode
or IUnknown
. For that to work, though, the interface type needs to include a GUID in its declaration, like this:
type
IMBNode = interface
['{GUID-goes-here}']
// methods and properties
end;
When the first parameter to Supports
is an interface reference, the function calls its QueryInterface
method. If it returns S_OK
, then Supports
return true; otherwise, it returns false. When the first parameter is an object reference, then it first calls the object's GetInterface
method to get its IUnknown
interface, and calls Supports
on that like before. If it doesn't work that way, then it falls back to asking for the requested interface directly from GetInterface
. If you've implemented QueryInterface
correctly on your object, or if you've used the default implementation from TInterfacedObject
, then everything should work fine.
If Supports
never returns true for you, then you should revisit some assumptions. Are you sure your node really supports the interface you're requesting? Go make sure the class declaration includes that interface. Make sure QueryInterface
is implemented properly. And make sure SomeNode
actually refers to the node you're expecting it to.
精彩评论