Usually we use CoCreateInstance or CoGetClassObject to get the interface and then access his member methods through the interface. With C + + support, there will never be any problems. But if you use Win32 mode, pure C-style programming, there will be problems.
Through the study I found that there are problems in this way of access. Standard access methods, such as D3D, the initialization of an interface must be done on the basis of the API provided by COM. The COM designer needs to provide an API that, like the DLL's exported function, supplies external program calls.
Specific design:
The following is a GDI extension function library Gdiex,gdiexcreate is a function of creating an interface, which, like direct3dcreate9, calls this function to create an interface pointer immediately.
Design the exported functions within COM, such as:
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;
}
This function can be placed in the primary CPP file.
In the exported header file (gdiex.h), make a declaration:
HRESULT WINAPI GdiexCreate(LPVOID *lplpGdiex);
The API is included in this header file as long as you do not regenerate com.
Down in Gdiex.def Add this API name for external access.
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObjectPRIVATE
DllRegisterServerPRIVATE
DllUnregisterServerPRIVATE
GdiexCreate
Call, you need to include gdiex.h in the project, input gdiex.lib, you can call to this API
ISaveDDCtl * pCtl = NULL;
CoInitialize( NULL );
hr = GdiexCreate( (LPVOID*) &pCtl );
if(FAILED( hr )) {
return hr;
}
... ...
GdiexFree( (LPVOID) &pCtl ); //gdiex释放API,在gdiex模块中定义。
CoUninitialize();
That is, the caller can get the interface without extra access. and C + + can work very well.