通常我们都是使用CoCreateInstance或CoGetClassObject获得接口再通过接口访问他的成员方法在C++支持下从来不会有任何问题但是如果使用Win模式纯粹C风格编程就会出现问题了 通过研究我发现其实上述访问方式本身就存在问题标准的访问方式如DD一样接口的初始化必须在Com提供的API基础上完成COM设计者需要提供一个API像DLL的导出函数一样供给外部程序调用 具体设计 下面是一个gdi扩展函数库gdiexGdiexCreate就是创建接口的一个函数如同DirectDCreate一样调用这个函数可以立刻创建一个接口指针 在COM内部设计导出函数如 HRESULT WINAPI GdiexCreate(LPVOID *lplpGdiex) { HRESULT hr; ISaveDDCtl * pCtrl = NULL; hr = CoCreateInstance( CLSID_SaveDDCtl NULL CLSCTX_SERVER IID_ISaveDDCtl (void**) &pCtrl); if(FAILED(hr)) { MessageBox(NULL GdiexCreate Failed! gdiexPS MB_OK|MB_ICONSTOP); return hr; } *lplpGdiex = (LPVOID) pCtrl; return S_OK; } 该函数可以放在主要cpp文件中 在导出的头文件(gdiexh)中作出声明 HRESULT WINAPI GdiexCreate(LPVOID *lplpGdiex) 只要不重新生成COM这个头文件中都会包含该API 下来在gdiexdef增加这个API名字以便外部访问 EXPORTS DllCanUnloadNowPRIVATE DllGetClassObjectPRIVATE DllRegisterServerPRIVATE DllUnregisterServerPRIVATE GdiexCreate 调用的时候只需要在工程中包含gdiexh 输入gdiexlib就可以调用到这个API ISaveDDCtl * pCtl = NULL; CoInitialize( NULL ); hr = GdiexCreate( (LPVOID*) &pCtl ); if(FAILED( hr )) { return hr; } GdiexFree( (LPVOID) &pCtl );//gdiex释放API在gdiex模块中定义 CoUninitialize(); 就是这样调用者没有出现多余的访问就可以获得接口而且C/C++都可以很好的工作 |