Directshow中Filter开发基础[7]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 aoosang 的 blog

*pv = (lpvoid) (lpunknown) new cclassfactory(pt);
if (*pv == null) {
return e_outofmemory;
}
((lpunknown)*pv)->addref();
return noerror;
}
}
return class_e_classnotavailable;
}

图4
下面我们看看类厂模板数组
类厂模板数组包含以下变量
const wchar * m_name; // name
const clsid * m_clsid; // clsid
lpfnnewcomobject m_lpfnnew; // function to create an instance of the component
lpfninitroutine m_lpfninit; // initialization function (optional)
const amoviesetup_filter * m_pamoviesetup_filter; // set-up information (for filters)
两个函数指针m_lpfnnew and m_lpfninit使用如下的定义
typedef cunknown *(callback *lpfnnewcomobject)
(lpunknown punkouter, hresult *phr);
typedef void (callback *lpfninitroutine)
(bool bloading, const clsid *rclsid);
第一个用来创建对象的实例函数,第二个函数是初始化函数,如果你定义了这个函数,在动态库dll的进入点函数就会调用这个初始化函数。
假设你定义了一个dll,这个dll包含了一个叫做cmycomponent组件,它继承与cunknown,你必须在你的dll定义下面的几个东西
1 一个创建你的组件的实例的公有函数。
2一个全局的类厂模板数组,名字一定要命名为g_templates,这个数组包含创建组件的类厂模板
3一个叫做全局变量g_ctemplates,这个变量用来表示类厂模板数组的大小。
下面是示例代码
// public method that returns a new instance.
cunknown * winapi cmycomponent::createinstance(lpunknown punk, hresult *phr)
{
cmycomponent *pnewobject = new cmycomponent(name("my component"), punk, phr );
if (pnewobject == null) {
*phr = e_outofmemory;
}
return pnewobject;
}

cfactorytemplate g_templates[1] =
{
{
l"my component", // name
&clsid_mycomponent, // clsid
cmycomponent::createinstance, // method to create an instance of mycomponent
null, // initialization function
null // set-up information (for filters)
}
};
int g_ctemplates = sizeof(g_templates) / sizeof(g_templates[0]);
类厂的createinstance方法调用组件的构造函数,并返回一个指向新类实例的一个指针。参数punk指向iunknown接口指针,看看我从基类里找到的createinstance函数的代码
stdmethodimp
cclassfactory::createinstance(
lpunknown punkouter,
refiid riid,
void **pv)
{
checkpointer(pv,e_pointer)
validatereadwriteptr(pv,sizeof(void *));

/* enforce the normal ole rules regarding interfaces and delegation */

if (punkouter != null) {
if (isequaliid(riid,iid_iunknown) == false) {
return resultfromscode(e_nointerface);
}
}

/* create the new object through the derived class's create function */

hresult hr = noerror;
cunknown *pobj = m_ptemplate->createinstance(punkouter, &hr);

if (pobj == null) {
if (succeeded(hr)) {
hr = e_outofmemory;
}
return hr;
}

/* delete the object if we got a construction error */

if (failed(hr)) {
delete pobj;
return hr;
}

/* get a reference counted interface on the object */

/* we wrap the non-delegating qi with ndaddref & ndrelease. */
/* this protects any outer object from being prematurely */
/* released by an inner object that may have to be created */
/* in order to supply the requested interface. */
pobj->nondelegatingaddref();
hr = pobj->nondelegatingqueryinterface(riid, pv);
pobj->nondelegatingrelease();
/* note that if nondelegatingqueryinterface fails, it will */
/* not increment the ref count, so the nondelegatingrelease */
/* will drop the ref back to zero and the object will "self-*/
/* destruct". hence we don't need additional tidy-up code */
/* to cope with nondelegatingqueryinterface failing. */

if (succeeded(hr)) {
assert(*pv);
}

return hr;
}
我们发现,类厂就是通过全局变量g_templates and g_ctemplates来创建组件的,所以,g_templates and g_ctemplates的名字不能改变
下面看看dll的导出函数
dll functions
一个动态库必须导出如下的函数,才能够注册,注销,加载。
? dllmain: the dll entry point. the name dllmain is a placeholder for the library-defined function name. the directshow implementation uses the name dllentrypoint. for more information, see the platform sdk. dshow没有dllmain,改用了dllentrypoint。进入点函数
? dllgetclassobject: creates a class factory instance. described in the previous sections.
? dllcanunloadnow: queries whether the dll can safely be unloaded.
? dllregisterserver: creates registry entries for the dll.
? dllunregisterserver: removes registry entries for the dll.
当然了,前面的三个函数,directshow已经替我们完成了,如果你的类厂模板数组中的m_lpfninit指针有一个初始化函数,那么在dll的入口函数就会被调用。
你自己必须要提供dllregisterserver and dllunregisterserver函数来实现组件的注册和反注册,但是directshow提供了提供了一个函数叫做amoviedllregisterserver2已经替你做完了必要的工作,所以你要做的就很简单了,只需如下就可以了
stdapi dllregisterserver()
{
return amoviedllregisterserver2( true );
}

本文关键:Directshow中Filter开发基础
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top