【问题标题】:MySQL Connector Issues - Linking and even moreMySQL 连接器问题 - 链接甚至更多
【发布时间】:2012-09-13 09:05:23
【问题描述】:

所以,我又来了,伙计们。经过一整天试图找出链接 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)。调试并没有太大帮助,因为这个错误在程序运行时就发生了,即即使我在开始时设置了无限循环,它仍然会崩溃。

所以,我想:“这应该是这个版本的一些错误,所以我必须尝试更新一个”。在此之后,我继续下载了 1.1.0 版的连接器以及 boost 库。比创建新项目,像第一个一样设置所有依赖项,但指向较新版本的连接器。除此之外,我设置了新的参考 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

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

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

另外,我已将 mysqlcppconn.lib 放入 Preferences -> Linker -> Additional Dependencies。

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

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

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

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

【问题讨论】:

    标签: c++ mysql visual-studio linker mysql-connector


    【解决方案1】:

    我遇到了同样的问题“无法正确启动 (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 复制到我的项目调试目录中。

    【讨论】:

      【解决方案2】:

      尝试创建一个新项目并仅创建一个简单的 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>
      

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

      }

      【讨论】:

      • 好吧,prepared_statement 和 statement 的用途完全不同,所以你不能只用另一个来代替。但是,我尝试按照您的说明进行操作,但程序仍然崩溃。
      • 只是看看你能不能编译它,你能告诉我你的程序崩溃的输出吗?有趣的是,如果您有描述的链接器错误,您没有将正确的库放入“GCC C++ 链接器选项卡”,添加 mysqlcppconn 它将工作,C++ Build --> Settings --> C++ Linker --> Libraries" mysqlcppconn"
      • 好吧,对于上面的代码,没有链接器错误 - 它与 application error 崩溃(即连接器 1.0.5)。还有一个带有链接器错误的库——它不可能是错误的库,原因很简单——连接器只有两个库:一个是 mysqlcppconn.lib,另一个是 mysqlcppconn-static.lib,前者用于动态链接器,后者用于- 对于静态。但是,正如 MySQL 网站所述,连接器不再支持更高版本的库,因此无法选择库。
      • 关于连接器 1.1.0 的确切链接器错误,如下:1&gt;MySQLConnectorC++Client_1.obj : error LNK2001: unresolved external symbol _get_driver_instance1&gt;D:\Repository\MySQLConnector\Release\MySQLConnector.exe : fatal error LNK1120: 1 unresolved externals
      • Monceber,几天前我遇到了完全相同的错误,现在如果您在 Windows 上,只有在 mingw 或 cygwin 路径定义错误(例如错误的子目录等)时,我才会遇到崩溃的应用程序。 ) 链接器错误肯定是因为您错误地链接了应用程序。我使用 libmysqlcppconn5 1.1.0-3build1。不要误会我的意思,但您可能包含冲突的 mysql 库以及将 64 位库与 32 位库混合使用
      【解决方案3】:

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

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

      工具: -依赖步行者(http://www.dependencywalker.com/) -进程监视器 (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来做到这一点。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-09
        • 2014-11-15
        • 2011-11-14
        • 2010-12-18
        相关资源
        最近更新 更多