AfxDaoTerm, and stuff
Ted -- tward@geographix.com Tuesday, April 09, 1996 Sorry if this has been discussed already, but I haven't received the list in awhile. I am using NT 3.51, VC 4.1. I am trying to open a DAO database in an OCX. My code does nothing but open, and close the database. When the app that calls the OCX tries to exit, the following happens: Appcore.cpp int CWinApp::ExitInstance() { if (!afxContextIsDLL) SaveStdProfileSettings(); // Cleanup DAO if necessary if (m_lpfnDaoTerm != NULL) { // If a DLL, YOU must call AfxDaoTerm prior to ExitInstance ASSERT(!afxContextIsDLL); (*m_lpfnDaoTerm)(); <- *******IMPORTANT PART******* } return m_msgCur.wParam; // returns the value from PostQuitMessage } The function pointer calls into the following code: Daocore.cpp void AFXAPI AfxDaoTerm() { _AFX_DAO_STATE* pDaoState = AfxGetDaoState(); // Close any CDaoWorkspaces left around void* pvKey; void* pvObject; POSITION pos = pDaoState->m_mapWorkspaces.GetStartPosition(); while (pos != NULL) { pDaoState->m_mapWorkspaces.GetNextAssoc(pos, pvKey, pvObject); ((CDaoWorkspace*)pvObject)->Close(); } pDaoState->m_mapWorkspaces.RemoveAll(); // Clean up engine object if necessary if (pDaoState->m_pDAODBEngine != NULL) { pDaoState->m_pDAODBEngine->Release(); <- *******CRASHES HERE****** pDaoState->m_pDAODBEngine = NULL; } // Shutdown OLE component objects if necessary if (pDaoState->m_bOleInitialized) { ::CoUninitialize(); pDaoState->m_bOleInitialized = FALSE; } // If hooked up to CWinApp, make sure to unhook CWinApp* pApp = AfxGetApp(); if (pApp != NULL) pApp->m_lpfnDaoTerm = NULL; } And the code crashes (access error 00005), I can't even trace into the Release() code, the crash happens immediately, but pointer is (obviously) not NULL. The comment in AppCore says that you must call AfxDaoTerm() before ExitInstance. I have tried calling AfxDaoTerm() from different places in my code (such as the ExitInstance routine, before calling the default handler), and sometimes it has no effect at all, and sometimes I get an assertion failure. But no matter what, it gets called again when the application exits. What is going on??? Anybody??? Thanks for any help. Please CC any replies to me. Ted Ward tward@geographix.com Denver, Colorado
MikeMike -- MikeMike@athens.emi.net Friday, April 12, 1996 [Mini-digest: 3 responses] Ted Check out Q143084 "Fix:Problems with Using the MFC DAO Classes in a .DLL or .OCX" You can find it at www.microsoft.com/kb under VC or in MSDN Mike Massa MIKEMIKE@MSN.COM MIKEMIKE@EMI.NET 407-626-2330 -----From: Ola GunnarsIm using the Dao in an MFC app (EXE) and there is something wrong in = this functionality. When runing 3.51 Im calling AfxDaoTerm() and = everything works fine but whenb runing under NT 4.0 the program crashes = so I needed to check version before calling this object . My code calls = ODBC and DAO and I have an query in DAO that calls an ODBC stored proc . = When I close all databases one ODBC database (CDatabase) object is = impossible to close something hangs in SQLDisconnect . /Ola -----From: Dan Kirby Hi, you must call AfxDaoTerm() after all of your DAO objects are destroyed but before ExitInstance(). In other words you can't wait until the DLL_PROCCESS_DETACH case to terminate DAO. This means that you cannot have Global DAO objects and you can't do something like: void SomeMethod() { CDaoDatabase db; db.Open(); . . . db.Close(); AfxDaoTerm(); } because AfxDaoTerm is called before the destruction of the DAO object. If you have: void SomeMethod() { CDaoDatabase * pDb= new DaoDatabase; db.Open(); . . . db.Close(); delete pDb; AfxDaoTerm(); } This is fine. --dan
| Вернуться в корень Архива |