MFC/OCX链接Directshow/strmbasd.lib出现的问题unresolved external symbol "class CFactoryTemplate * g_Templates"

来源:互联网 发布:博士德进销存软件 编辑:程序博客网 时间:2024/05/29 15:08

在一个MFC/OCX项目中链接

winmm.lib//        VS自带PLATFORM SDK

strmbasd.lib//    DIRECTSHOW

两个静态库的时候出现了以下链接错误

 

1>strmbasd.lib(dllentry.obj) : error LNK2001: unresolved external symbol "class CFactoryTemplate * g_Templates" (?g_Templates@@3PAVCFactoryTemplate@@A)

1>strmbasd.lib(dllentry.obj) : error LNK2001: unresolved external symbol "int g_cTemplates" (?g_cTemplates@@3HA)

显然是后者出现了问题。

当初看了下directshow中baseclasses项目的源码

 

 

于是我自作聪明地定义了预处理宏FILTER_DLL,然后OCX编译通过,貌似已经解决,但是在引用该OCX的时候,CoGetClassObject总是返回CLASS_E_CLASSNOTAVAILABLE,

C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/include/winerror.h

 

// MessageId: CLASS_E_CLASSNOTAVAILABLE

//

// MessageText:

//

//  ClassFactory cannot supply requested class

//

#define CLASS_E_CLASSNOTAVAILABLE        _HRESULT_TYPEDEF_(0x80040111L)

我搜索了下注册表,也找到了控件的注册信息。

由于我是在DEBUG模式下编译OCX,所以是自注册的,当我用REGSVR32手动注册的时候出现了LOADLIBRARY失败的提示。

于是断点跟踪,APP等一切初始化都正常,但C:/Program Files/Microsoft Visual Studio 8/VC/atlmfc/src/mfc/oledll.cpp

AfxDllGetClassObject函数并没有进入。于是我掉进了MFC源码的大海。

今天艰苦爬上岸,重新开始,决定回到问题的源头,在网上搜到了一篇文章

http://www.codeguru.com/forum/archive/index.php/t-282715.html。

 

原因:

The problem exists because you end up linking in strmbase.lib which has entry points functions for DllGetClassObject() and DllCanUnloadNow() among others. You really don't want these entry points
defined in for your ActiveX control. They are designed for DirectShow filters, and require g_Templates to be defined by your filter.

One solution is to override the following functions by implementing them into your ActiveX control yourself. That way you don't pull in the ones from the DShow.

因为BaseClasses/dllentry.cpp

定义了接口函数,OCX应该调用的C:/Program Files/Microsoft Visual Studio 8/VC/atlmfc/src/mfc/oleexp.cpp

DllGetClassObject被其重载。(英语水平不佳,用词可能欠妥,请见谅。)

 

解决途径:

在实例源文件中添加函数