所以,我又来了。在尝试找出连接libmysql.lib和mysqlclient.lib的解决方案一整天之后,我已经彻底完成了。所以,在那里,我决定采用另一种方式并使用方便的MySQL连接器。
由于它的1.1.0版本使用了boost,我没有提供,并且不想花时间计算一切,我决定下载1.0.5。
所以,我安装了它,创建了新项目,链接了所有必要的库,设置了额外的库和包含(通常,根据this手册完成所有操作。为了测试它是否正常工作,我使用了样本像这样:
#include <stdlib.h>
#include <iostream>
#include "driver.h"
#include "exception.h"
#include "resultset.h"
#include "statement.h"
#include "prepared_statement.h"
int main(){
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
sql::PreparedStatement *pstmt;
try{
driver = get_driver_instance();
con = driver->connect("localhost", "root", "root");
con->setSchema("test");
/*blah blah yada yada*/
}catch(sql::SQLException &e){
std::cout<<e.what();
}
}
我跳过部分代码,因为这不是重点。所以,问题是应用程序错误告诉无法正确启动(0xc000007b)。调试没有太大帮助,因为一旦程序运行就会发生这个错误,即使我在开头放置无限循环,它仍然会崩溃。
所以,我想:“应该是这个版本的一些bug,所以我必须尝试更新的”。在此之后,我继续下载1.1.0版本的连接器以及升级库。比创建新项目,设置所有依赖项就像第一个,但指向较新版本的连接器。除此之外,我设置了新的参考mysqlcppconn_EXPORTS。所以,准备工作已经完成,出于测试目的,我使用了来自MySQL site的代码,通常,这样的代码:
/*tons of includes here*/
int main(int argc, const char *argv[]) {
Driver *driver;
Connection *con;
Statement *stmt;
ResultSet *res;
PreparedStatement *prep_stmt;
Savepoint *savept;
int updatecount = 0;
/* initiate url, user, password and database variables */
string url(argc >= 2 ? argv[1] : DBHOST);
const string user(argc >= 3 ? argv[2] : USER);
const string password(argc >= 4 ? argv[3] : PASSWORD);
const string database(argc >= 5 ? argv[4] : DATABASE);
try {
driver = get_driver_instance();
/*blah blah yada yada*/
} catch (std::runtime_error &e) {
cout << "ERROR: runtime_error in " << __FILE__;
//cout << " (" << __func__ << ") on line " << __LINE__ << endl;
cout << "ERROR: " << e.what() << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
} // main()
猜猜是什么?是的,这里再次出现链接器错误:
error LNK2001: unresolved external symbol _get_driver_instance
所以请有人告诉我,我做错了什么?非常感谢。
我会明确说明并用粗体字写,所以不会以这种方式回答。我已经定义了两个首选项 - &gt; C / C ++ - &gt;一般 - &gt;其他包含目录以及首选项 - &gt;链接器 - &gt;一般 - &gt;其他图书馆目录。
另外,我已将mysqlcppconn.lib
添加到偏好设置 - &gt;链接器 - &gt;附加依赖。
此外,我已将mysqlcppconn.dll
和libmysql.dll
(是的,从相应的C ++连接器版本中)放入我的项目文件夹中,不会出现任何问题。
哦,是的,我在预处理器定义中尝试使用和不使用CPPCONN_PUBLIC_FUNC=
键 - 没有发生任何更改。
正如我所说的那样 - 在相同的项目首选项中,1.0.5版的连接器在构建阶段和版本1.1.0失败 - 在编译阶段。
P.S。我正在使用VS 2010,我的操作系统--Windows 7 x64。项目和库都是x32。
答案 0 :(得分:2)
我遇到了同样的问题“无法正确启动(0xc000007b)”。问题是我没有使用正确的DLL(使用x86而不是x64),即使我已经安装(并重新安装)了64位的mysql。
我已添加到PATH变量“C:\ MySQL \ Connector C ++ 1.1.3 \ lib \ opt”,其中mysqlcppconn.dll(对于x64)位于此处。然而,在我的PATH中有另一个目录(lua安装),它有mysqlcppconn.dll(用于x86)。由于x86目录在MySQL目录之前设置了x86 dll,因此“无法启动...”
为了避免这种情况,我将mysqlcppconn.dll复制到我的项目调试目录。
答案 1 :(得分:0)
尝试创建一个新项目,只需创建一个简单的数据库连接器,我没有可用的窗口,所以我只能告诉你我的linux示例:
我可以看到的区别是你使用的是prepared_statement,你可以尝试一下这个语句,只在你的链接器中包含mysqlcppconn.dll,看看这个“小项目”是否编译?也许你有太多的库,但是一个简单的测试可以更容易地识别你的问题,如果这解决了你的问题而不是你知道这些库不应该相互包含。
如果这不起作用告诉我,我会尝试扩展答案。
这是我的包含:
#include "mysql_connection.h"
#include "mysql_driver.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
int main(){
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
sql::Statement *pstmt;
try{
driver = get_driver_instance();
con = driver->connect("localhost", "root", "root");
con->setSchema("test");
stmt = conn->createStatement();
/*blah blah yada yada*/
}catch(sql::SQLException &e){
std::cout<<e.what();
}
}
答案 2 :(得分:0)
我有同样的“无法启动”问题,经过多次痛苦后,解决了它。不幸的是,你在第一篇文章中的免责声明说你已经尝试过我的解决方案了,但我会发布我过去向自己证明我错误类型的DLL的过程(我最初也确定我使用的是正确的bittage DLL)。如果你仍然确定你已经获得了DLL / LIB的正确位置,那么请转到“使用进程监视器进行调试”部分。
我的问题是我的构建后脚本是从错误的位置复制DLL。我花了很多时间来确保我的DLL目录中有正确的东西,但事实证明我的后期构建脚本没有从该目录复制,因此将x64 DLL与我的x86应用程序一起复制。
工具: -Dependancy walker(http://www.dependencywalker.com/) -Process Monitor(http://technet.microsoft.com/en-ca/sysinternals/bb896645.aspx)
步骤: - 制作一个没有问题的编译和运行的项目。我制作了一个控制台应用程序并粘贴在MySQL连接器示例代码中。它在下面。请注意,我已经使用#pragma comment(lib)来包含lib,所以你甚至不需要乱用库包含,只需要包含目录。
/* Copyright 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
There are special exceptions to the terms and conditions of the GPL
as it is applied to this software. View the full text of the
exception in file EXCEPTIONS-CONNECTOR-C++ in the directory of this
software distribution.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Standard C++ includes */
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
/*
Include directly the different
headers from cppconn/ and mysql_driver.h + mysql_util.h
(and mysql_connection.h). This will reduce your build time!
*/
#include "mysql_connection.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#pragma comment(lib,"mysqlcppconn.lib")
#pragma comment(lib,"libmysql.lib")
using namespace std;
int main(void)
{
cout << endl;
cout << "Running 'SELECT 'Hello World!' AS _message'..." << endl;
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "password");
/* Connect to the MySQL test database */
con->setSchema("test");
stmt = con->createStatement();
res = stmt->executeQuery("SELECT 'Hello World!' AS _message");
while (res->next()) {
cout << "\t... MySQL replies: ";
/* Access column data by alias or column name */
cout << res->getString("_message") << endl;
cout << "\t... MySQL says it again: ";
/* Access column fata by numeric offset, 1 is the first column */
cout << res->getString(1) << endl;
}
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line "<< __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
cout << endl;
return EXIT_SUCCESS;
}
如果在设置目录后该代码不起作用,那么您确实需要仔细检查您使用的DLL和LIB是否是正确的32/64位数。你可以使用dependency walker来做到这一点。
如何使用依赖性walker: 1)将DLL或EXE拖到DepWalk窗口。在丑陋的模块列表(日志上方的窗口)中,找到您拖入的DLL / EXE,并确保CPU列中的CPU类型符合您的预期。
进程监视器调试: 如果上面的玩具代码为你编译,那么现在你在说话!你有一个正常启动的示例应用程序,而没有正确启动的应用程序应用程序。启动进程监视器,将过滤器设置为仅包含您的玩具应用程序,然后运行它。文件 - &gt;保存该日志,将过滤器更改为损坏的应用程序的进程名称,然后使用损坏的应用程序再次执行此操作。现在你可以比较两个应用程序运行mySQL DLL的内容,也许可以找出它们在哪里破坏。在我的情况下,我注意到它正在正确的位置加载libmysql.dll,然后在其他位置搜索它。我正确地推断出这意味着我有错误的LibMySQL.dll。这可能不是你的问题,但我打赌你会得到一些关于过程监控的见解。