MySQL C++ Connector 在 ResultSet->getString() 上使我的应用程序崩溃
MySQL C++ Connector crashes my app at ResultSet->getString()
可能又是我在问c++新手问题
我有很大的头痛使该死的(对不起的语言)MySQL c++连接器工作。我不知道这是写得不好还是怎么的,但就我的经验而言,我从来没有遇到过这么多的麻烦。
无论如何,我得到它连接和抛出异常失败的连接/查询,这对我来说是相当大的事情:U: p。实际的问题来自于我获取查询的结果。无论我做什么,我的应用程序总是崩溃:S
我使用32位安装程序和libmysql.dll/lib从32位MySQL服务器(因为我正在编译一个32位应用程序,我认为这是正确的事情)
这里有一些代码你可以想象我在说什么
DBManager.h
#ifndef DBMANAGER_H
#define DBMANAGER_H
#define CPPCONN_PUBLIC_FUNC
#define CPPCONN_LIB_BUILD True
#include <string>
#include "mysql_connection.h"
#include "mysql_driver.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
class DBManager
{
public:
static DBManager* Instance();
bool Query(const char* Query);
void Connect(const char* DbHost, unsigned short DbPort, const char* DbUser, const char* DbPass, const char* DbName);
bool ValidCredentials(const char* Username, const char* Password);
void ManageException(sql::SQLException &e);
~DBManager();
protected:
static DBManager* pInstance;
private:
DBManager() {};
DBManager(DBManager const&){};
DBManager& operator=(DBManager const&){};
sql::mysql::MySQL_Driver* driver;
sql::Connection *Con;
sql::PreparedStatement *pstmt;
sql::ResultSet *res;
sql::Statement *stmt;
bool isConnected;
};
#endif
现在cpp文件DBManager.cpp
#include "DBManager.h"
DBManager* DBManager::pInstance = NULL;
DBManager* DBManager::Instance()
{
if (!pInstance)
{
pInstance = new DBManager();
}
return pInstance;
}
bool DBManager::Query(const char* Query)
{
return true;
}
DBManager::~DBManager()
{
delete Con;
delete pstmt;
delete res;
delete stmt;
}
void DBManager::ManageException(sql::SQLException& e)
{
if (e.getErrorCode() != 0) {
std::cout << "# ERR: SQLException in " << __FILE__;
std::cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << std::endl;
std::cout << "# ERR: " << e.what();
std::cout << " (MySQL error code: " << e.getErrorCode();
std::cout << ", SQLState: " << e.getSQLState() << " )" << std::endl;
}
}
void DBManager::Connect(const char* DbHost, unsigned short DbPort, const char* DbUser, const char* DbPass, const char* DbName)
{
try {
driver = sql::mysql::get_mysql_driver_instance();
std::string connDSN = "tcp://" + std::string(DbHost) + ":3306";
Con = driver->connect(connDSN, sql::SQLString(DbUser), sql::SQLString(DbPass));
Con->setSchema(sql::SQLString(DbName));
isConnected = true;
std::cout<<"Database connection successul."<<std::endl;
} catch(sql::SQLException &e) {
ManageException(e);
isConnected = false;
return;
}
}
bool DBManager::ValidCredentials(const char* Username, const char* Password)
{
bool cred = false;
try {
pstmt = Con->prepareStatement("SELECT * FROM account WHERE account_name=? LIMIT 1"); // Smart use of indexing
pstmt->setString(1, Username);
res = pstmt->executeQuery();
while(res->next())
{
if (res->getString("password") == Password)
{
cred = true;
}
}
}
catch(sql::SQLException &e) {
ManageException(e);
return false;
}
return cred;
}
基本上,它编译没有问题,连接没有问题,执行查询没有问题,但第二个我试图检索数据,一些断点异常在文件"xutils.cpp"中抛出。我真的不知道我做错了什么。我在编译调试时使用DEBUG库。嗯,libmysql.dll应该发布,因为我从服务器包中提取了它,但我似乎没有找到它作为编译我自己的源代码。
我真的不知道为什么它会这样崩溃和燃烧:/
PS:不要介意密码的无散列,这对我来说真的只是一个概念的证明……让它先工作,然后保护它:U
PS:我也有Boost库编译和准备在项目中,如果这有帮助:U
EDIT: Main function
bool ServerRunning = true;
int main(int argc, char** argv)
{
#ifdef _WIN32
std::string title = TEXT("Window Title Change");
SetConsoleTitle(title.c_str());
#endif;
std::cout<<"Loading Configuration File..."<<std::endl<<std::endl;
std::string path = boost::filesystem::path(boost::filesystem::current_path()).string();
path += "\Config.ini";
INIParser* Config = new INIParser(path.c_str()); //MinINI
// Sockets data
std::string listenIP = Config->GetString("Network", "ListenIP", "127.0.0.1");
unsigned short listenPort = Config->GetInt("Network", "ListenPort", 5000);
// Database data
std::string dbHost = Config->GetString("Database", "Host", "localhost");
std::string dbUser = Config->GetString("Database", "User", "root");
std::string dbPass = Config->GetString("Database", "Password", "");
std::string dbName = Config->GetString("Database", "Database", "authserv");
unsigned short dbPort = Config->GetInt("Database", "Post", 1000);
// General settings
int sessionTimeout = Config->GetInt("Settings", "SessionTimeout", 10);
int maxClients = Config->GetInt("Settings", "MaxClients", 10);
int serverTimeout = Config->GetInt("Settings", "GameserverTimeout", 1);
// Begin Initialization
DBManager::Instance()->Connect(dbHost.c_str(), dbPort, dbUser.c_str(), dbPass.c_str(), dbName.c_str());
bool loginSuccess = DBManager::Instance()->ValidCredentials("Username", "Password");
char c;
while (ServerRunning)
{
std::cin>>c;
if (c == 'q')
{
ServerRunning = false;
}
}
return 0;
}
假设password
字段在数据库中定义为varchar
,则不能使用getString()
来检索它。您必须使用blob
函数,getBlob()
。
这是while
循环的样子:
while(res->next())
{
std::istream * retrievedPassword_stream = res->getBlob("password");
if (retrievedPassword_stream)
{
char pws[PASSWORD_LENGTH+1]; // PASSWORD_LENGTH defined elsewhere; or use other functions to retrieve it
retrievedPassword_stream->getline(pws, PASSWORD_LENGTH);
std::string retrievedPassword(pws); // also, should handle case where Password length > PASSWORD_LENGTH
if (retrievedPassword == std::string(Password))
{
cred = true;
}
}
}
侧边注释:请注意,代码中还有一些其他问题。
- 必须删除语句句柄,因此应该在
- 在使用
pstmt
,res
或Con
之前一定要检查NULL。 -
stmt
似乎是未使用的,不应该被删除。
ValidCredentials()
函数的适当位置执行delete pstmt;
(而不是在析构函数中)。(但是,在这种情况下为什么要使用准备好的语句呢?最好在构造函数(或调用查询的函数之外的其他地方)中初始化预处理语句,以及在析构函数或其他地方删除使用预处理语句。但是,请注意,准备好的语句对于高使用率和高cpu密集型查询最有用,因此在这里使用它进行密码验证可能并不重要(您可以只执行常规查询,而不是执行准备好的语句)。同样,ResultSet需要在try块的末尾删除(delete res
),而不是在析构函数中。- 下载mysql c++连接器 编译mysqlcppconn-static项目使用mt或mtd添加CPPCONN_LIB_BUILD
- 您的项目添加(2)构建的静态库
相关文章:
- 为什么我的多线程作业队列崩溃
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 指针相关的UE4崩溃.我的指针哪里错了?
- 拖放我的MDI被CRichEditView拦截并在CRichEditView::GetDocument中崩溃 - 如何覆
- 为什么我的结构在包含字符串时崩溃?
- 无法访问的代码如何导致我的程序崩溃?
- 矢量迭代器在尝试调用函数时使我的程序崩溃
- 使用唯一指针调用函数会使我的程序崩溃
- 钩/绕道 d3d9 (现在/结束场景) - 似乎调用我的函数然后崩溃
- C++单例模板类使我的程序崩溃
- 我的程序在到达"cin << ans1 "时崩溃
- 运行简单的.oct文件时Octave崩溃,我的代码出了什么问题?
- 是什么导致我的 Python 紧缩 C 扩展崩溃?
- 我的单例中的数组在离开函数后没有保留信息,然后在尝试再次访问信息时崩溃
- 我的程序在调用 vkCmdBindDescriptorSet 时崩溃
- LOCAL_SHARED_LIBRARIES使我的应用程序崩溃
- 为什么使用 nullPtr 调用函数不会使我的应用程序崩溃
- 当我尝试将一个向量元素的值分配给另一个向量元素时,为什么我的应用程序会崩溃
- 如果我使用此功能,我的控制台崩溃
- 为什么我的程序在这一行崩溃