+ -
当前位置:首页 → 问答吧 → DLL中声明并初始化了COM接口指针,如何析构掉?

DLL中声明并初始化了COM接口指针,如何析构掉?

时间:2011-11-30

来源:互联网

一个VC6 exe程序,调用VC6的DLL,而该DLL又调用了一个COM

VC6 exe程序 -- vc6exe.cpp

#define MYDECL __stdcall//__cdecl
typedef BOOL (MYDECL *InitPlotter_type)();
InitPlotter_type InitPlotter_ptr = NULL;

HMODULE hDll = 0;

void CSimWplotterDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here

hDll = LoadLibrary("vc6dll.dll");

 
  InitPlotter_ptr = (InitPlotter_type ) GetProcAddress( hDll, "InitPlotter");
   
  InitPlotter_ptr();

}

VC6 DLL ---vc6dll.cpp

#import "PlotterCom.tlb"

PlotterCom::IPlotterInterfacePtr p_PlotterCom = NULL;


BOOL __stdcall InitPlotter(void)
{
if (p_PlotterCom == NULL)
{
PlotterCom::IPlotterInterfacePtr p(__uuidof(PlotterCom::XLpPlotter ));
p_PlotterCom = p;
}
bool inited = p_PlotterCom->VB_InitPlotter();
//p_PlotterCom=NULL;
return inited;
}

BOOL __stdcall PausePlot(void)
{
return p_PlotterCom->VB_PausePlot();

}


上面的//p_PlotterCom=NULL;
//注释掉此句,在关闭退出时,会报错
//加上此句退出时虽然不会报错。但是这个全局指针我还需要使用,在调用COM中的其它函数时使用(比如PausePlot()),因为一些参数是在InitPlotter()函数内初始化的,且InitPlotter()函数会弹出一个窗口,继续手动初始化参数。所以该指针不能重新初始化,必须是全局指针。

我希望能在使用完该DLL,需要退出程序时,再使用p_PlotterCom=NULL;。避免程序退出时出错。
请问,在DLL中何处添加该句代码,才能达到我的目的?

作者: neighbornet   发布时间: 2011-11-30

在程序退出时调p_PlotterCom->Release()

作者: yayafu   发布时间: 2011-11-30

如果用了MFC,在App类的exitinstance函数里调,否则在Dllmain中的DLL_PROCESS_DETACH分支中调

作者: yayafu   发布时间: 2011-11-30

没有使用MFC,所以尝试着按您所说的在

BOOL APIENTRY DllMain( HMODULE hModule,
  DWORD ul_reason_for_call,
  LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:

p_PlotterCom->Release();//加上此句,还是报错,是不是和我调用vc6dll.dll的方式有关呢?
break;
}
return TRUE;
}

引用 2 楼 yayafu 的回复:
如果用了MFC,在App类的exitinstance函数里调,否则在Dllmain中的DLL_PROCESS_DETACH分支中调

作者: neighbornet   发布时间: 2011-11-30

PlotterCom::IPlotterInterfacePtr是怎么定义的,是普通指针还是智能指针,它内部怎么管理对象引用的

作者: yayafu   发布时间: 2011-11-30