断开与SQLite数据库的连接时崩溃 我试图编写一个C++程序,它将与不同的数据库提供者通信。现在一切正常,但是退出后我试图关闭连接,disconnect命令崩溃。目前我正在用SQLite进行测试,所以它可能属于这个特定的版本
我是否必须在程序终止时关闭与SQLite的连接?我相信一般来说,释放程序正在使用的资源是一个好主意,但是这个案例呢?我的意思是,在这种情况下,当程序退出时,SQLite DB文件将被释放回系统,因此它实际上不是一个丢失 多谢各位 [编辑] 根据要求,我正在提交我使用的代码 在DLL1(database.h)中: 在DLL1(database.cpp)中断开与SQLite数据库的连接时崩溃 我试图编写一个C++程序,它将与不同的数据库提供者通信。现在一切正常,但是退出后我试图关闭连接,disconnect命令崩溃。目前我正在用SQLite进行测试,所以它可能属于这个特定的版本,c++,sqlite,dll,virtual-destructor,C++,Sqlite,Dll,Virtual Destructor,我是否必须在程序终止时关闭与SQLite的连接?我相信一般来说,释放程序正在使用的资源是一个好主意,但是这个案例呢?我的意思是,在这种情况下,当程序退出时,SQLite DB文件将被释放回系统,因此它实际上不是一个丢失 多谢各位 [编辑] 根据要求,我正在提交我使用的代码 在DLL1(database.h)中: 在DLL1(database.cpp)中 #包括 #包括“database.h” 数据库::数据库() { } 数据库::~数据库() { } void*数据库::运算符新建(标准::大
#包括
#包括“database.h”
数据库::数据库()
{
}
数据库::~数据库()
{
}
void*数据库::运算符新建(标准::大小\u t大小)
{
返回::运算符新(大小);
}
void数据库::运算符删除(void*ptr,std::size\u t size)
{
返回::操作员删除(ptr);
}
在DLL2:(database_sqlite.h)中:
\ifndef DBMANAGER\u SQLITE
#定义DBMANAGER_SQLITE
类uu declspec(dllexport)SQLiteDatabase:公共数据库
{
公众:
SQLiteDatabase();
虚拟~SQLiteDatabase();
虚拟整数连接(const char*selectedDSN、std::vector和errorMsg);
受保护的:
void GetErrorMessage(int代码,std::wstring和errorMsg);
私人:
sqlite3*m_db;
};
#恩迪夫
在DLL2中:(database_sqlite.cpp)
#ifdef WIN32
#包括
#杂注执行字符集(“utf-8”)
#恩迪夫
#包括
#包括
#包括
#包括“sqlite3.h”
#包括“database.h”
#包括“database_sqlite.h”
SQLiteDatabase::SQLiteDatabase():Database()
{
}
SQLiteDatabase::~SQLiteDatabase()
{
sqlite3_关闭(m_db);
}
int SQLiteDatabase::Connect(const char*selectedDSN、std::vector和errorMsg)
{
int结果=0;
std::wstring错误消息;
int res=sqlite3_open(selectedDSN和m_db);
如果(res!=SQLITE_OK)
{
//获取错误消息GetErrorMessage(res,errorMessage);
errorMsg.推回(errorMessage);
结果=1;
}
其他的
{
res=sqlite3_exec(m_db,“PRAGMA-foreign_-keys=ON”,NULL,NULL,NULL);
如果(res!=SQLITE_OK)
{
//获取错误消息GetErrorMessage(res,errorMessage);
errorMsg.推回(errorMessage);
结果=1;
}
}
返回结果;
}
在DLL3中:(dialogs.cpp)
\ifdef\uu GNUC__
#pragma实现“dialogs.h”
#恩迪夫
#ifdef__BORLANDC__
#布拉格语hdrstop
#恩迪夫
#包括
#包括“sqlite3ext.h”
#包括“database.h”
#包括“database_sqlite.h”
#ifdef_窗口
BOOL APIENTY DllMain(手柄模块、DWORD FDREASON、LPVOID LPREFERED)
{
lpReserved=lpReserved;
hModule=hModule;
int argc=0;
字符**argv=NULL;
开关(FDSON)
{
案例DLL\u进程\u附加:
打破
案例DLL\u进程\u分离:
打破
}
返回TRUE;
}
#恩迪夫
外部“C”uu declspec(dllexport)数据库*数据库配置文件(数据库*db)
{
db=新的SQLITE数据库;
返回分贝;
}
在主应用程序(测试应用程序cpp)中:
#包括“stdafx.h”
#包括“database.h”
#包括
#包括
typedef数据库*(uu cdecl*MYFUNC)(数据库*);
甲级
{
公众:
A(数据库*db)
{
m_db=NULL;
HINSTANCE hInst=LoadLibrary(文本(“dialogs.dll”);
MYFUNC func=(MYFUNC)GetProcAddress(hInst,“数据库配置文件”);
m_db=func(db);
}
~A()
{
}
数据库*GetDatabase()
{
返回m_db;
}
私人:
数据库*m_db;
};
int _tmain(int argc,_TCHAR*argv[]
{
数据库*db=NULL,*m_db;
A*A=新的A(db);
m_db=a->GetDatabase();
删除m_db;
删除一条;
返回0;
}
[编辑]
运行这段代码,我得到了执行“delete”m_db“行的崩溃。SQLite是从源代码编译而来的
有什么想法吗
谢谢。如果能看到导致崩溃的代码,那就太好了。@ForceBru,基本上我已经创建了一个SQLite包装并将其放入DLL中。然后在另一个DLL中,我创建了一个此类的对象并将其传递回主应用程序。当主应用程序退出时,它正在崩溃,试图在SQLite内获取全局锁。I c我今天下班后会发布一些代码。请显示一个。@CL.,正如我所说的,我稍后会发布代码。但是,我必须独立地关闭连接吗?你应该这样做。你有双重空闲或内存损坏,无论如何都应该修复。
#ifndef DBMANAGER_DATABASE
#define DBMANAGER_DATABASE
class __declspec(dllexport) Database
{
public:
Database();
virtual ~Database();
static void *operator new(size_t size);
static void operator delete(void *ptr, size_t size);
};
#endif
#include <string>
#include "database.h"
Database::Database()
{
}
Database::~Database()
{
}
void *Database::operator new(std::size_t size)
{
return ::operator new( size );
}
void Database::operator delete(void *ptr, std::size_t size)
{
return ::operator delete( ptr );
}
#ifndef DBMANAGER_SQLITE
#define DBMANAGER_SQLITE
class __declspec(dllexport) SQLiteDatabase : public Database
{
public:
SQLiteDatabase();
virtual ~SQLiteDatabase();
virtual int Connect(const char *selectedDSN, std::vector<std::wstring> &errorMsg);
protected:
void GetErrorMessage(int code, std::wstring &errorMsg);
private:
sqlite3 *m_db;
};
#endif
#ifdef WIN32
#include <windows.h>
#pragma execution_character_set("utf-8")
#endif
#include <vector>
#include <string>
#include <sqlext.h>
#include "sqlite3.h"
#include "database.h"
#include "database_sqlite.h"
SQLiteDatabase::SQLiteDatabase() : Database()
{
}
SQLiteDatabase::~SQLiteDatabase()
{
sqlite3_close( m_db );
}
int SQLiteDatabase::Connect(const char *selectedDSN, std::vector<std::wstring> &errorMsg)
{
int result = 0;
std::wstring errorMessage;
int res = sqlite3_open( selectedDSN, &m_db );
if( res != SQLITE_OK )
{
// get error messages GetErrorMessage( res, errorMessage );
errorMsg.push_back( errorMessage );
result = 1;
}
else
{
res = sqlite3_exec( m_db, "PRAGMA foreign_keys = ON", NULL, NULL, NULL );
if( res != SQLITE_OK )
{
// get error message GetErrorMessage( res, errorMessage );
errorMsg.push_back( errorMessage );
result = 1;
}
}
return result;
}
#ifdef __GNUC__
#pragma implementation "dialogs.h"
#endif
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include <vector>
#include "sqlite3ext.h"
#include "database.h"
#include "database_sqlite.h"
#ifdef _WINDOWS
BOOL APIENTRY DllMain( HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
lpReserved = lpReserved;
hModule = hModule;
int argc = 0;
char **argv = NULL;
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif
extern "C" __declspec(dllexport) Database *DatabaseProfile(Database *db)
{
db = new SQLiteDatabase;
return db;
}
#include "stdafx.h"
#include "database.h"
#include <windows.h>
#include <stdio.h>
typedef Database *(__cdecl *MYFUNC)(Database *);
class A
{
public:
A(Database *db)
{
m_db = NULL;
HINSTANCE hInst = LoadLibrary( TEXT( "dialogs.dll" ) );
MYFUNC func = (MYFUNC) GetProcAddress( hInst, "DatabaseProfile" );
m_db = func( db );
}
~A()
{
}
Database *GetDatabase()
{
return m_db;
}
private:
Database *m_db;
};
int _tmain(int argc, _TCHAR* argv[])
{
Database *db = NULL, *m_db;
A *a = new A( db );
m_db = a->GetDatabase();
delete m_db;
delete a;
return 0;
}