You can think of QueryInterface
simply as a COM type-cast.
QI, or QueryInterface
, is a term used by the Microsoft COM specification. The specification is a binary standard that is language agnostic (it can be implemented by various languages).
From Microsoft's documentation on COM:
The Microsoft Component Object Model (COM) is a platform-independent,
distributed, object-oriented system for creating binary software
components that can interact.
To understand COM (and therefore all COM-based technologies), it is
crucial to understand that it is not an object-oriented language but a
standard. Nor does COM specify how an application should be
structured; language, structure, and implementation details are left
to the application developer. Rather, COM specifies an object model
and programming requirements that enable COM objects (also called COM
components, or sometimes simply objects) to interact with other
objects. These objects can be within a single process, in other
processes, and can even be on remote computers. They can be written in
different languages, and they may be structurally quite dissimilar,
which is why COM is referred to as a binary standard; a standard that
applies after a program has been translated to binary machine code.
In other words, as long as your compiler can produce binary objects that adhere to the COM binary standard, they can interact with each other, no matter what language they were originally written in. COM-compliant compilers exist for Java, C++, C#, VB.NET, and several other languages.
Anyway, you asked specifically what QueryInterface was. So at the root of all COM components, there is an interface called IUnknown
, which has three methods: AddRef
, QueryInterface
and Release
. When using most languages that do automatic garbage collection (such as languages based on the Java or .NET runtime), the developer does not need to interact with AddRef
and Release
– since the memory management is (most of the time) handled correctly by the proxies that get generated automatically by the language or IDE that is being used. I mentioned the proxies because this is relevant to you in Java.
So that leaves QueryInterface
. QueryInterface
is the method that is used to fetch another interface implemented by the same COM object.
QueryInterface
has the following properties:
The set of interfaces accessible on an object through QueryInterface
must be static, not dynamic. This means that if a call to QueryInterface
for a pointer to a specified interface succeeds the first time, it must succeed again, and if it fails the first time, it must fail on all subsequent queries.
It must be reflexive – if a client holds a pointer to an interface on an object, and queries for that interface, the call must succeed.
It must be symmetric – if a client holding a pointer to one interface queries successfully for another, a query through the obtained pointer for the first interface must succeed.
It must be transitive – if a client holding a pointer to one interface queries successfully for a second, and through that pointer queries successfully for a third interface, a query for the first interface through the pointer for the third interface must succeed.
QueryInterface
is the basic way that we navigate through all the objects that make up ArcObjects. You may also want to read the MS documentation that clarifies how to navigate COM Objects through QueryInterface
.
If you look at the ESRI documentation, you will find that, for example, the FeatureClass
co-class supports several COM interfaces. You can "hop" the different interfaces through QueryInterface
.
In each language, the act of hopping interfaces or QI'ing, is done with different syntaxes, although semantically it is the same. For example, the C# and VB.NET compilers transform regular type-casts on a COM interface to the corresponding call to QueryInterface
, e.g.:
IFeatureClass featureClass = someFeatureWorkspace.OpenFeatureClass(…);
IDataset dataset = (IDataset)featureClass;
// ^^^^^^^^^^^^^^^^^^^^^^
// the C# compiler turns this into a call to QueryInterface.