我对com技术很陌生,但我想要做的是为com创建一个基本的包装器,特别是音频com (mmdevapi)。它应该是这样工作的:我的程序调用一个com(也是由我创建的),它最终将加载并返回指向音频接口的指针。我试图使一切尽我所能透明,但我需要更多的信息,调用时,加载一个com。据我理解:
1. Because the dll is loaded in the same memory as the program it can use this pointer to access the methods from the interface.
如果我写的所有内容都是正确的,那么这应该符合我的需要(这是主程序使用的包装器com的一部分):
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppvObj) {
//main();
//print iid from here..
LPOLESTR s;
StringFromCLSID(rclsid, &s);
OutputDebugStringW(s);
CoTaskMemFree(s);
StringFromCLSID(riid, &s);
OutputDebugStringW(s);
CoTaskMemFree(s);
//prints: {BCDE0395-E52F-467C-8E3D-C4579291692E} -the audio clsid
// {00000001-0000-0000-C000-000000000046} -the requested interface
// {D3C5025B-3634-4F74-9404-942ECEFC1152} -contains the dll for audio
static const GUID custom_Audio_GUID =
{ 0xd3c5025b, 0x3634, 0x4f74,{ 0x94, 0x4, 0x94, 0x2e, 0xce, 0xfc, 0x11, 0x52 } };
CoInitialize(NULL);
CoCreateInstance(custom_Audio_GUID, NULL, CLSCTX_INPROC_SERVER, riid, ppvObj); //The program wants to access an interface from the audio com so I have to bypass this com,load the audio and request the interface and pass it to the program
return S_OK;
}因此,对于这个程序,它没有什么应该做的(它可以使用QueryInterface,使用我的com返回的ppvObj等)获取其余的接口。但是,当然,它不起作用。它加载音频dll,生成代理项,但音频不工作。有什么想法吗?
(自定义CLSID在clsid中的CURRENT_USER中定义。它只包含InprocServer32 32/默认-no单元配置;我还没有定义DLLCanUnload,但我不认为这是个问题)。
发布于 2017-10-01 22:07:43
最后我解决了这个问题。什么问题?我不能使用CoGetClassObject或CoCreateInstance,因为这些函数加载了音频dll,并使用自定义clsid调用了DllGetClassObject,在该定制clsid下移动了mmdevapi.dll (原来的clsid现在承载了dll)。由于com属性,dll可以承载许多“对象”,其中每个对象都由clsid表示。每个对象都包含由IID标识的接口。现在,Chrome通常使用clsid ( by 0395-E52F-467C-8E3D-C4579291692E})调用DllGetClassObject of mmdevapi.dll。在它的DllGetClassObject函数中,它试图通过查看程序传递给这个函数的clsid (在一个长if语句或开关中)来找出这个类。如果找到匹配的clsid,则返回匹配的接口,Chrome也指定了该接口的iid。
在我的例子中,我试图从mmdevapi获得与Chrome相同的接口(因为我将它的调用转发给DllGetClassObject),使用以下代码:
CoGetClassObject(custom_Audio_GUID, NULL, CLSCTX_INPROC_SERVER, riid, ppvObj);但是,custom_Audio_GUID与请求的clsid不同,所以mmdevapi总是返回CLASS_E_CLASSNOTAVAILABLE。
我的解决方案:
HMODULE dll=LoadLibrary("mmdevapi.dll"); //I can load the exact dll I need,without the registry lookup
Func load=(load)GetProcAddr(dll,"DllGetClassObject");
load(rclsid, riid, ppvObj); //and I can pass the exact params I want在我试图绕过com的过程中,这对我起了作用。(我是新来的,所以我的理解中肯定有错误,也许是术语上的错误,但这就是我理解错误的方式)。
https://stackoverflow.com/questions/46513274
复制相似问题