我做了很多谷歌搜索,试图找到获取 COM 接口实例的标准方法。
微软在他们的文章中提供了一个例子COM 互操作第 1 部分:客户端教程 https://msdn.microsoft.com/en-us/library/aa645736(v=vs.71).aspx:
// Create an instance of a COM coclass:
FilgraphManager graphManager = new FilgraphManager();
// See if it supports the IMediaControl COM interface.
// Note that this will throw a System.InvalidCastException if
// the cast fails. This is equivalent to QueryInterface for
// COM objects:
IMediaControl mc = (IMediaControl) graphManager;
// Now you call a method on a COM interface:
mc.Run();
然而,看起来好像他们正在实例化一个 COM 对象并将其转换为 COM 接口。
对于我感兴趣的界面,IDesktopWallpaper
,似乎没有实现 COM 对象来实例化。
我找到的一个例子here http://www.dreamincode.net/forums/topic/298478-problems-implementing-idesktopwallpaper-com-interface/定义一些被实例化的类,然后将其转换为接口,与 msdn 示例的方式相同:
[ComImport, Guid("C2CF3110-460E-4fc1-B9D0-8A1C0C9CC4BD")]
internal class IDesktopWallpaper
{
}
[Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B"), //B92B56A9-8B55-4E14-9A89-0199BBB6F93B
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface DesktopWallpaperInterface
{
// declared members
}
我不明白实例化的对象是什么。它看起来像一个任意的物体,它有一个GuidAttribute
这似乎表明它是一个实际的 COM 对象。
我发现的另一个例子here https://www.codeproject.com/Articles/3551/C-does-Shell-Part System.Type
and System.Runtime.InteropServices.Marshal
实例化一个对象,然后将其强制转换为接口:
IntPtr ptrRet;
SHGetMalloc(out ptrRet);
System.Type mallocType = System.Type.GetType("IMalloc");
Object obj = Marshal.GetTypedObjectForIUnknown(ptrRet,mallocType);
IMalloc pMalloc = (IMalloc)obj;
该方法似乎正在请求指向该接口的现有实例的指针。我找不到类似的方法SHGetMalloc
for IDesktopWallpaper
在 Windows Shell 文档中。
Question
那么,长话短说,获取 COM 接口实例的标准方法是什么?
如果没有一刀切的解决方案,那么标准是什么?ways可以用来获取 COM 接口的实例,在什么情况下这些方法最有用?
Edit
下载 Windows 10 SDK 并根据要求部分引用它后IDesktopWallpaper 接口文档 https://msdn.microsoft.com/en-us/library/windows/desktop/hh706946(v=vs.85).aspx,我发现你可以从以下位置查找 MIDLShobjidl.h
并在中使用它GuidAttribute
获取接口声明,然后查找 CLSIDShobjidl.idl
并将其与Type.GetTypeFromCLSID(Guid)
and Activator.CreateInstance(Type)
获取实现的对象的实例IDesktopWallpaper
.
我现在还看到,CLSID 是上面列出的第二种方法中使用的GuidAttribute
看似随意的物体。看起来这个方法允许您通过实例化类然后将实例转换为 COM 接口来模拟对象的托管实例化。
However我仍然有兴趣知道这是否是执行此操作的最佳方法以及此方法与其他方法相比有何优缺点。