我编写了一个 Windows Mobile 下的 Directshow Filter,但是如何注册却成了问题。在 Windows 下面只要使用 Regsvr32 即可,但是这个程序在 Windows Mobile 的模拟器中不存在。
首先参考 MSDN:Registering DirectShow Filters,Creating a DLL in DirectShow。
为了偷懒,我决定使用 eMbedded Visual C++ 4.0(下载)附带的 RegsvrCE.exe 来注册 DLL。把 regsvrce.exe 和 dllname.dll 一起复制到模拟器中,设法运行(比如编一个小程序)"regsvrce.exe dllname.dll"即可。
中间我还遇到了一个小问题,当我注册一个 Filter 的时候,返回错误:
Loadlibrary("dllname.dll") failed. GetLastError returns 7e.
错误代码 7e 的含义是没有找到特定的模块,应该是这个 DLL 调用了当前系统中不存在的 DLL。经过检查发现是我在编译 Filter 的时候,运行时库选择了"多线程 DLL(/MD)",而它所需要的 msvcr90.dll 在模拟器中似乎不存在。于是我从 Visual Studio 目录下面的把相应的 msvcr90.dll 复制到模拟器然后注册,就可以注册我的 Filter 了。如果不想复制这个文件,把运行时库改为"多线程(/MT)"也可以。
如何在程序中使用"RegsvrCE.exe",下面有一个例子:
SHELLEXECUTEINFO ShExecInfo = {0}; ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb = NULL; ShExecInfo.lpFile = _T("regsvrce.exe"); ShExecInfo.lpParameters = _T("Program Files\\H264VideoDecoder\\H264VideoDecoder.ax"); ShExecInfo.lpDirectory = NULL; ShExecInfo.nShow = SW_SHOW; ShExecInfo.hInstApp = NULL; ShellExecuteEx(&ShExecInfo); WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
其实还有一个好的方法,就是在路其明的《DirectShow 开发指南》第10页介绍的方法。在应用程序中使用 LoadLibrary 装载这个 Filter 文件,找到它的导出函数 DllRegisterServer(或 DllUnregisterServer)的入口地址,然后执行它即可。不过书中的参考代码有些错误,就是在 typedef 的时候,下面是修改后的代码:
BOOL RegisterFilter(LPCWSTR inFilterAx) { typedef HRESULT (WINAPI * REGISTER_FUNC) (void); REGISTER_FUNC MyFunc = NULL; HMODULE hModule = ::LoadLibrary(inFilterAx); if (hModule) { MyFunc = (REGISTER_FUNC) GetProcAddress(hModule, _T("DllRegisterServer")); BOOL pass = (MyFunc != NULL); if (pass) { MyFunc(); } ::FreeLibrary(hModule); return pass; } return FALSE; }
使用的时候,只需要调用:
RegisterFilter(_T("Storage Card\\H264VideoDecoder.ax"));
搞什么程序?
我做的是视频播放,所以用DirectShow,以前也没怎么接触过这些。
发表评论