首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >COM包装调用链C++

COM包装调用链C++
EN

Stack Overflow用户
提问于 2017-10-01 14:17:18
回答 1查看 332关注 0票数 2

我对com技术很陌生,但我想要做的是为com创建一个基本的包装器,特别是音频com (mmdevapi)。它应该是这样工作的:我的程序调用一个com(也是由我创建的),它最终将加载并返回指向音频接口的指针。我试图使一切尽我所能透明,但我需要更多的信息,调用时,加载一个com。据我理解:

  1. CoInitialize被称为
  2. CoCreateInstance: 在注册表中搜索dll。 b.装入图书馆 在DllGetClassObject上获取地址(我想它不会检查其他函数DllCanUnloadNow) 跳转到传递程序请求的clsid的函数(每个对象有一个clsid,所以一个dll中有多个对象?(每个包含多个类的“对象”?)界面的身份。 DllGetClassObject返回一个指向接口的空指针。
代码语言:javascript
复制
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的一部分):

代码语言:javascript
复制
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,但我不认为这是个问题)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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),使用以下代码:

代码语言:javascript
复制
CoGetClassObject(custom_Audio_GUID, NULL, CLSCTX_INPROC_SERVER, riid, ppvObj);

但是,custom_Audio_GUID与请求的clsid不同,所以mmdevapi总是返回CLASS_E_CLASSNOTAVAILABLE。

我的解决方案:

代码语言:javascript
复制
  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的过程中,这对我起了作用。(我是新来的,所以我的理解中肯定有错误,也许是术语上的错误,但这就是我理解错误的方式)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46513274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档