CoCreateInstance 异常。在静态库上使用 REGSVR32 进行类注册?

Posted

技术标签:

【中文标题】CoCreateInstance 异常。在静态库上使用 REGSVR32 进行类注册?【英文标题】:CoCreateInstance exception. Class registration using REGSVR32 on a static library? 【发布时间】:2016-03-29 18:17:38 【问题描述】:

代码(来自我为 Win32 平台构建的 c++ com 服务器项目的 sn-p,在我的 c# 应用程序中):

CComPtr<IMSPRProvider> test;
hr = CoCreateInstance(CLSID_MSPRProvider, NULL, CLSCTX_ALL, IID_IMSPRProvider, reinterpret_cast<void**>(&test));

HR:regdb_e_classnotreg。类未注册

在同一个项目中,我有一个较旧的 WMDRM drm 实现,可以很好地与 cocreateinstance 调用配合使用。所以这个问题是新的 playready 类所特有的。

我看到其他有关此异常的问题,建议使用 regsvr32.exe 注册 dll。如果这是解决方案,我有两个问题:

    我从来不需要注册其他任何东西(比如 WMDRM 的东西),为什么要这样? 我正在使用 PlayReady SDK,它包含一些已链接到我的项目中的 .h、.idl 和 .lib 文件。我没有动态库。静态库的等效解决方案是什么?

PS:我对 c++ 的经验几乎为零。我是认真的,所以如果我没有提供足够的细节,我很抱歉。

【问题讨论】:

【参考方案1】:

CoCreateInstance 使用某种需要可用的服务器创建一个实例。在大多数情况下,服务器是一个 DLL,需要先向 regsvr32 注册,以便将相关 CLSID 写入全局列表中,并且 API 知道如何查找实现。

我从不需要注册其他任何东西(比如 WMDRM 的东西),为什么要这样?

REGDB_E_CLASSNOTREG表示服务器没有注册,所以需要注册。如果您以前从未这样做过,那么您已经通过其他方式为您完成了。

我正在使用 PlayReady SDK,它包含一些已链接到我的项目中的 .h、.idl 和 .lib 文件。我没有动态库。静态库的等效解决方案是什么?

静态库没有等价物。 CoCreateInstance 使用标准 API 创建一个实例。如果链接实现,则根本不需要静态库。但是,您的“静态库”很可能只是前端和/或声明,真正的实现在动态加载库中。因此CoCreateInstance 和注册。

您需要注意的另一件事是 32/64 位混淆。您的代码应该与 DLL 的位数相匹配。如果不匹配,您可能会再次遇到REGDB_E_CLASSNOTREG 问题。

【讨论】:

所以它不是注册可播放(或 wmdrm)的东西,而是我的 com 服务器项目本身。我会调查的;如果它有效,我会解决这个问题。非常感谢。 如果引用的代码行导致这个错误,那么它是关于实现CLSID_MSPRProvider类的COM服务器(可能是DLL)的注册。 我明白了。 ATL 向导为我的类添加了它自己的 .rgs com 注册器脚本,而不是将新类附加到主 .rgs。这就是为什么它适用于该项目的其他以前的课程,这就是为什么我不必手动使用 regsvr32 做任何事情。通过手动编辑脚本,我注册了新类并且 CoCreateInstance 工作。非常感谢您让我朝着正确的方向前进。解决方案实际上是 Visual Studio 配置文件管理的问题。

以上是关于CoCreateInstance 异常。在静态库上使用 REGSVR32 进行类注册?的主要内容,如果未能解决你的问题,请参考以下文章

静态库上的 Xib 文件

COM笔记-CoCreateInstance

在 VS 2012 中调用 CoCreateInstance 期间符号加载缓慢

在 COM 中:我应该在 CoCreateInstance 之后调用 AddRef 吗?

关于 CoCreateInstance() 方法实现的问题

CoCreateInstance 返回“类未注册”