Access Violation when ADO is used from global object exported from MFC extensions DLL (VC++) 
Author Message
 Access Violation when ADO is used from global object exported from MFC extensions DLL (VC++)

Hi!
I am in the process of converting a VC++ legacy application from DAO to ADO.
The way this application works is it has a class that encapsulates the
database access defined in a DLL and a global object of this type is
exported from the DLL and used as a singleton.  All calls to the database
are made via this object.  I discovered that when I added an ADO
_ConnectionPtr  member to database encapsulation object and called
CreateInstance() it caused an access violation in MSDART.DLL when the
application exit.

I dont understand why this is.  I did discover that if right after the call
to CreateInstance() I added a call to AddRef() the access violation goes
away.  (see code below)  While this solves my problem its just black magic
as I dont understand whats going on.  I would truly appreciate if somebody
could explain this to me.  I have reproduced this in a minimal standard MFC
project and will be glad to send it to anybody or you can follow the
instructions bellow to reproduce yourself.

Any help would be greatly appreciated (code sample follows signature)
Thanks
  Joey

To reproduce the error:
* Create an MFC extension DLL project add the CMyDB class to it.  (Minimal
code is at bottom of message) .
* Create a standard MFC wizard app SDI app in the doc object include the
"MyDB.h"  and add a call       TheDB.ForceDllLoad(5,6); to the
OnNewDocument()

Run the app.  When you exit you should receive the access violation.

// MyDB.h: interface for the CMyDB class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MYDB_H__B670CD08_CCE1_4C15_9FE1_D27E59A6F4FC__INCLUDED_)
#define AFX_MYDB_H__B670CD08_CCE1_4C15_9FE1_D27E59A6F4FC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <comdef.h>
#import "E:\Program Files\Common Files\System\ADO\msado15.dll"
rename_namespace("NSADO") rename("EOF", "EndOfFile")
#include "icrsint.h"
using namespace NSADO;

inline void TestHR( HRESULT _hr )
   { if FAILED(_hr) _com_issue_error(_hr); }

class AFX_EXT_CLASS CMyDB
{
public:
      int ForceDllLoad(int a,int b);
      CMyDB();
      virtual ~CMyDB();
      _ConnectionPtr  m_pDenXDBADO;

Quote:
};

// define the DataBase access class to be global
// defined as external in .h and
// defined in .cpp ( so it will
// be alocated only once).

extern CMyDB AFX_EXT_CLASS TheDB;

#endif //
!defined(AFX_MYDB_H__B670CD08_CCE1_4C15_9FE1_D27E59A6F4FC__INCLUDED_)

// MyDB.cpp: implementation of the CMyDB class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MyDB.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

CMyDB  AFX_EXT_CLASS TheDB;      // DataBase defined as a global.

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMyDB::CMyDB()
{
      CoInitialize(NULL);

      try {
            HRESULT hr =
pDenXDBADO.CreateInstance( __uuidof( NSADO::Connection ) );
            TestHR(hr);
//  Uncomment next line to prevent access violation.
//          m_pDenXDBADO.AddRef();
            if (SUCCEEDED(hr))
            {
                  CString connectStr;

connectStr.Format(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=db1.mdb;Persist Security Info=False"));

                  hr = m_pDenXDBADO->Open(
                        (LPCSTR) connectStr,
                        _bstr_t(L""),
                        _bstr_t(L""),
                        adModeShareDenyNone);
                  TestHR(hr);
            }

      }
      catch (_com_error &e)
      {
            CString str;
            str.Format(

"Error:%08lx.\nErrorMessage:%s.\nSource:%s.\nDescription:%s.\n",
                  e.Error(), e.ErrorMessage(),(LPCTSTR) _bstr_t(e.Source()),
                  (LPCTSTR) _bstr_t(e.Description()));
            AfxMessageBox(str);

    }

Quote:
}

CMyDB::~CMyDB()
{
      CoUninitialize( );  // <-- this seems to make no diffrence

Quote:
}

// Silly do nothing functin that forces the DLL to be loaded
// and global object to be initialized.
int CMyDB::ForceDllLoad(int a, int b)
{
      return a+b;
Quote:
}



Sat, 24 May 2003 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. Access Violation when ADO is used from global object exported from MFC extensions DLL (VC++)

2. How to export a class from Extension MFC dll to another Extension MFC dll

3. weird access violation ATL-ADO object

4. Access Violation using ADO in VC++

5. ACCESS VIOLATION WHEN USING ADO (???)

6. Help for Access violation using HtmlHelp in MFC

7. Help on Accessing ADO Objects Using VC via import

8. Access Violation after exiting exported DLL function

9. Shell extension using MFC extension DLLs

10. Open Connection Access Violation for ADO in ATL COM

11. Help Please! ADO Access Violation in VC++

12. ADO and access violation

 

 
Powered by phpBB® Forum Software