做一个TTS发音的DLL,代码如下:#include "stdafx.h"
#include <sapi.h>#pragma comment(lib,"ole32.lib") //CoInitialize CoCreateInstance需要调用ole32.dll
#pragma comment(lib,"sapi.lib") //sapi.lib在SDK的lib目录,必需正确配置
void WINAPI speak(LPCWSTR sts);
void init();
void rel();
ISpVoice * pVoice = NULL;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
init(); //DLL调用初始化voice
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
rel(); //程序退出时释放voice
break;
}
return TRUE;
}
void WINAPI speak(LPCWSTR sts) //TTS发音
{
pVoice->Speak(sts, 1, NULL);
}void init() //voice初始化
{
::CoInitialize(NULL); //COM初始化: //获取ISpVoice接口:
CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
}void rel() //释放PVOICE
{
pVoice->Release();
pVoice = NULL;
::CoUninitialize();
}
想在调用DLL的程序退出时,将voice释放,所以在dllmain中有:
case DLL_PROCESS_DETACH:
rel(); //程序退出时释放voice
break;
但是,一加上rel();就出错,只好将这个代码去掉,结果就运行正常了。不知这是怎么回事。
#include <sapi.h>#pragma comment(lib,"ole32.lib") //CoInitialize CoCreateInstance需要调用ole32.dll
#pragma comment(lib,"sapi.lib") //sapi.lib在SDK的lib目录,必需正确配置
void WINAPI speak(LPCWSTR sts);
void init();
void rel();
ISpVoice * pVoice = NULL;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
init(); //DLL调用初始化voice
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
rel(); //程序退出时释放voice
break;
}
return TRUE;
}
void WINAPI speak(LPCWSTR sts) //TTS发音
{
pVoice->Speak(sts, 1, NULL);
}void init() //voice初始化
{
::CoInitialize(NULL); //COM初始化: //获取ISpVoice接口:
CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
}void rel() //释放PVOICE
{
pVoice->Release();
pVoice = NULL;
::CoUninitialize();
}
想在调用DLL的程序退出时,将voice释放,所以在dllmain中有:
case DLL_PROCESS_DETACH:
rel(); //程序退出时释放voice
break;
但是,一加上rel();就出错,只好将这个代码去掉,结果就运行正常了。不知这是怎么回事。
1、启动组件得到一个接口指针(Interface)后,不要调用AddRef()。因为系统知道你得到了一个指针,所以它已经帮你调用了AddRef()函数;
2、通过QueryInterface()得到另一个接口指针后,不要调用AddRef()。因为......和上面的道理一样;
3、当你把接口指针赋值给(保存到)另一个变量中的时候,请调用AddRef();
4、当不需要再使用接口指针的时候,务必执行Release()释放;
5、当使用智能指针的时候,可以省略指针的维护工作;
不过,现在做的DLL也没发现内存泄露问题,先这么用着了。另,将rel() 中的 pVoice->Release();和 pVoice = NULL;这两行代码去掉,就可以正常使用了。
void rel() //释放PVOICE
{
// pVoice->Release();
// pVoice = NULL;
::CoUninitialize();
}