Reputation: 193
I am trying to implement some COM interfaces that can be used while exporting Word documents as PDF. Some of these interfaces don't inherit from IUnknown
, for instance:
#undef INTERFACE
#define INTERFACE IMsoServerFileManagerSite
DECLARE_INTERFACE(IMsoServerFileManagerSite)
{
STDMETHOD_(BOOL, FGetHandle) (const WCHAR *pwzFileName, HANDLE *phFile, BOOL fRead, BOOL fWrite) PURE;
STDMETHOD_(BOOL, FCloseHandle) (HANDLE hFile) PURE;
};
I found that I can translate these interfaces to IDL if I use the local attribute (declaring that they aren't remote). For instance
[
local,
uuid(f8e47685-e402-4119-aa07-4ea4ff1f1123)
]
interface IMsoServerFileManagerSite
{
BOOL FGetHandle(const WCHAR *pwzFileName, HANDLE *phFile, BOOL fRead, BOOL fWrite);
BOOL FCloseHandle(HANDLE hFile);
}
Another such interface, IMsoDocExporter
, does inherit from IUnknown
, but has some functions that return void
rather than HRESULT
. When I pass an object implementing this interface to the Word API I can attach a debugger and see that my dll is being called by functions like combase.dll!CRemoteUnknown::RemQueryInterface
.
So my questions are:
Does combase.dll!CRemoteUnknown::RemQueryInterface
mean that my object is being queried remotely? (i.e. I'll need a proxy/stub, and can't use the [local]
attr?)
if an interface uses non-automation types, such as HANDLE
, and doesn't return an HRESULT
can it still be marshalled?
is there a way/what is the best way to translate these interfaces to IDL so that MIDL will provide the proxy/stub implementation? (e.g. MIDL reference suggested that call_as could be used to map these functions to remote callable functions -- still unclear what I could do with HANDLE
though)
Upvotes: 0
Views: 207
Reputation: 193
After some more playing around I finally managed to make it work. @molbdnilo and @Jonathan Potter were correct. Only the IMsoDocExporter
interface is a COM object, and it inherits from IUnknown
. The other interfaces are just plain vtables I suppose and it seems that they can't be marshalled (at least not without writing lots of custom proxy/stub code).
- Does combase.dll!CRemoteUnknown::RemQueryInterface mean that my object is being queried remotely?
Yes, but this only applied to IMsoDocExporter
(the actual COM object)
- if an interface uses non-automation types, such as HANDLE, and doesn't return an HRESULT can it still be marshalled?
It turns out yes. As mentioned in my original post you can mark these methods [local]
and then define a similar method with the [call_as]
attribute that returns HRESULT
and has RPC-able parameters. Then you just need to define the functions that translates one call to the other. Ultimately, to marshal a HANDLE
you need to specify the type information.
Upvotes: 1