I was asked a question:
In VFP9 I am attempting to access StructuredStorage via the stgOpenStorageEx function in OLE32.DLL (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stg/stg/stgopenstorageex.asp).
I am ok with that. The catch here is ppObjectOpen, "... [out] The address of an interface pointer variable that receives a pointer for an interface on the storage object opened (contains NULL if operation failed)...". This is actually the IStorage interface.
Here I loose it! How do I define the IStorage interface in order to call its methods etc?
This question can be generalized: Some WIN APIs return interface pointers that are not associated with any objects. How can they be used?
COM Interface pointers are just C++ pointers (32 bit addresses) to C++ objects which have vTables. See Microsoft Visual FoxPro and Advanced COM and Advanced VFP Servers
When VFP does a CreateObject, internally CoCreateInstance is called to instantiate the object and return a COM Interface pointer. This pointer must inherit from IDispatch, which is the late binding COM interface. When a method is called on the object, the IDispatch::GetIDsOfNames method is called to get the ID of the method, then the IDispatch::Invoke method is called.
One of the uses of CreateObjectEx allows the caller to create an object and call it via early binding. This requires either a type library to be available or accurate type info to be returned via IDispatch::GetTypeInfo. Similarly with the GetInterface function, which uses an already created COM object in VFP to get an early bound interface.
To call methods of these interfaces pointer via VB6, VB7, or VC the program needs to have header files or a typelib at compile time. For VB, that means adding a Reference to the object. For VC that means to #import or #include the right files. Then VB and VC can compile (hard-code, or early bind) the calls to the methods on these objects.
If you don’t have a COM object and you get a COM Interface, as with StgOpenStorageEx, then VFP has no way to know how the vTable is laid out and thus has no way to call the members. The easiest way to use these COM Interface pointers is to use the Fox LCK to write the code in VC. Another solution would be to use SYS(3096), perhaps combined with GetInterface SYS(3096) allows the user to take a 32 bit number and interpret it as an IDispatch COM object. Since StgOpenStorageEx doesn’t inherit from IDispatch, this won’t wok.
Alternatively, what is the bigger picture? Perhaps there’s an alternate to calling StgOpenStorageEx that will solve the original goal. GetObject, or Windows Scripting Host may help.
COM servers that are created with VFP can be called via early or late binding. The early binding is done through the magic of VFP generating vTables that point to VFP generated machine code, but that’s another story.