4

所以,我又来了,伙计们。经过一整天试图找出链接 libmysql.lib 和 mysqlclient.lib 的解决方案后,我彻底完成了。所以,在那里,我决定采取另一种方式,使用方便的 MySQL 连接器。

由于它的 1.1.0 版本使用了 boost,而我没有它,也不想花时间去弄清楚一切,我决定下载 1.0.5。

所以,我安装了它,创建了新项目,链接了所有必要的库,设置了额外的库和包含(嗯,通常,根据手册完成所有事情。为了测试它是否正常工作,我使用了这样的示例:

#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)。调试并没有太大帮助,因为这个错误在程序运行时就发生了,即即使我在开始时设置了无限循环,它仍然会崩溃。

所以,我想:“这应该是这个版本的一些错误,所以我必须尝试更新一个”。在此之后,我继续下载了 1.1.0 版的连接器以及 boost 库。比创建新项目,像第一个一样设置所有依赖项,但指向较新版本的连接器。除此之外,我设置了新的参考 mysqlcppconn_EXPORTS。因此,准备工作已经完成,出于测试目的,我使用了MySQL 站点的代码,一般来说,是这样的:

/*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

所以请任何人告诉我我做错了什么?将不胜感激。

我会明确说明并用粗体字写出来,这样就不会有任何答案。我已经明确设置了 Preferences -> C/C++ -> General -> Additional Include Directories 以及 Preferences -> Linker -> General -> Additional Library Directories。

另外,我已经把mysqlcppconn.libPreferences -> Linker -> Additional Dependencies。

此外,我已将mysqlcppconn.dlland libmysql.dll(是的,来自各自的 C++ 连接器版本)放入我的项目文件夹中,对此没有任何问题。

哦,是的,我CPPCONN_PUBLIC_FUNC=在预处理器定义中尝试了使用和不使用键 - 没有发生任何变化。

正如我所说的那样 - 在相同的项目偏好下,连接器的 1.0.5 版本在构建阶段失败,而 1.1.0 版本在编译阶段失败。

ps 我正在使用 VS 2010,我的操作系统 - Windows 7 x64。项目和库都是 x32。

4

3 回答 3

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 复制到我的项目调试目录中。

于 2013-12-30T18:26:58.927 回答
0

尝试创建一个新项目并创建一个简单的 DB 连接器,我这里没有可用的窗口,所以我只能向您展示我的 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>

诠释主要(){

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();
    }

}

于 2012-09-13T10:12:50.293 回答
0

我有同样的“无法启动”的问题,经过很痛苦,解决了。不幸的是,您在第一篇文章中的免责声明说您已经尝试过我的解决方案,但我会发布我用来向自己证明我有错误类型的 DLL 的过程(我最初也确定我使用的是正确的 bittage DLL)。如果您仍然非常确定自己拥有正确的 DLL/LIB,那么请前往“使用进程监视器进行调试”部分。

我的问题是我的构建后脚本从错误的位置复制了一个 DLL。我花了很多时间试图确保我的 DLL 目录中包含正确的内容,但事实证明我的构建后脚本没有从该目录复制,因此在我的 x86 应用程序旁边复制 x64 DLL。

工具:-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 位。你可以使用依赖walker来做到这一点。

如何使用依赖漫游器: 1) 将 DLL 或 EXE 拖到 DepWalk 窗口中。在丑陋的模块列表(日志上方的窗口)中,找到您拖入的 DLL/EXE,并确保 CPU 列中的 CPU 类型是您期望的。

Process Monitor Debugging:如果上面的玩具代码是为您编译的,那么现在您正在说话!你有一个可以正常启动的示例应用程序,而你的坏应用程序不能正常启动。启动进程监视器,设置过滤器以仅包含您的玩具应用程序,然后运行它。文件->保存该日志,将过滤器更改为损坏的应用程序的进程名称,然后对损坏的应用程序再次执行此操作。现在您可以比较这两个应用程序在 mySQL DLL 中运行的内容,并可能找出它们在哪里出现问题。就我而言,我注意到它在正确的位置加载 libmysql.dll,然后在其他位置寻找它。我正确推断这意味着我有错误的 LibMySQL.dll。这可能不是你的问题,但我敢打赌,你会通过进程监视器获得一些见解。

于 2012-12-28T17:27:59.060 回答