web-dev-qa-db-fra.com

Connexion à MySQL en C++

J'essaie d'apprendre le C++ et j'ai un peu de cauchemar à faire un test où je me connecte à une base de données MySQL. 

J'ai eu des problèmes avec le connecteur MySQL qui ne liait pas correctement alors il y avait des problèmes liés à relocation truncated to fitr_x86_64_32 against symbol

Je pense avoir résolu ce problème en ajoutant un indicateur de compilateur et que l'application génère et crée des liens avec succès. 

Lorsque je lance l'application, cela va jusqu'à appeler get_driver_instance mais ensuite, ça se ferme. Aucune exception n'est levée, aucune erreur, rien que le code de sortie 0. 

Ci-dessous ma classe DBManager

#include "DBConnectionManager.h"

using namespace std;

DBConnectionManager::DBConnectionManager() {
    cout << "Starting DBConnectionManager - Updated" << endl;
    try {
        cout << "Getting driver instance" << endl;
        driver = get_driver_instance();
        cout << "Got driver instance" << endl;
        conn = driver->connect("tcp://127.0.0.1:3306", "root", "password");
        conn->setSchema("bugs");
        cout << "Connected to database" << endl;
    }
    catch (SQLException ex) {
        cout << "Error connecting to DB: " << ex.what() << endl;
    }
    catch (...) {
        cout << "Something has gone wrong" << endl;
    }
}

Ci-dessous le fichier d'en-tête

#ifndef MYSQLTEST_DBCONNECTIONMANAGER_H
#define MYSQLTEST_DBCONNECTIONMANAGER_H
#include <driver.h>
#include <exception.h>
#include <resultset.h>
#include <statement.h>

using namespace sql;

class DBConnectionManager
{
private:
    sql::Driver *driver;
    sql::Connection *conn;
    sql::Statement *statement;
    sql::ResultSet *res;
public:
    DBConnectionManager();
    void performSql();
};
#endif //MYSQLTEST_DBCONNECTIONMANAGER_H

Ci-dessous ma méthode principale

#include "DBConnectionManager.h"

int main() {
    DBConnectionManager dbConnectionManager;
    dbConnectionManager.performSql();
    return 0;
}

Ci-dessous mon fichier CMakeLists.txt

cmake_minimum_required(VERSION 3.6)
project(MySQLTest)

include_directories("C:\\Program Files\\MySQL\\MySQL Connector C++ 1.1.7\\include\\cppconn" "C:\\Program Files\\MySQL\\MySQL Connector C++ 1.1.7\\lib\\opt")

SET(GCC_COVERAGE_LINK_FLAGS    "-m64 -Wl,--image-base -Wl,0x10000000 -lpthread -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -m64 -Wl,--image-base -Wl,0x10000000 -lpthread -pthread ")

set(SOURCE_FILES main.cpp DBConnectionManager.cpp)
add_executable(MySQLTest ${SOURCE_FILES})
add_library(mysqlcppconn.lib)

set_target_properties(MySQLTest PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(mysqlcppconn.lib PROPERTIES LINKER_LANGUAGE CXX)

target_link_libraries(MySQLTest "C:\\Program Files\\MySQL\\MySQL Connector C++ 1.1.7\\lib\\opt\\mysqlcppconn.lib")

Lorsque je crée l'instance de ma classe DBConnectionManager, elle appelle avec succès la requête et imprime Starting DBConnectionManager - Updated suivie de Getting Driver Instance, mais elle se ferme alors avec Process finished with exit code 0 sans laisser de traces de ce qui ne va pas. 

Mettre à jour

J'arrive enfin à quelque chose. J'ai découvert qu'il y a des bibliothèques clientes MySQL dans Cygwin. Je les ai donc téléchargées et référencées dans le fichier cmake. 

Mon fichier cmake ressemble maintenant à ceci:

cmake_minimum_required(VERSION 3.6)
project(MySQLTest)

SET(CPPCONN_PUBLIC_FUNC=)

SET(GCC_COVERAGE_LINK_FLAGS    "-g -m64 -DCPPCONN_PUBLIC_FUNC= -Dmysqlcppconn_EXPORTS -lpthread -pthread -Wl,--image-base -Wl,0x10000000  -lz")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCPPCONN_PUBLIC_FUNC= -Dmysqlcppconn_EXPORTS -std=c++11 -g -m64 -Wl,--image-base -Wl,0x10000000  -lpthread -pthread  -lz")

include_directories("C:/mysql_connector/include")
include_directories("C:/boost_1_61_0")

set(BOOST_INCLUDE_DIR C:/boost_1_61_0)
set(BOOST_LIBRARY_DIR C:/boost_1_61_0/libs)
set(SOURCE_FILES main.cpp DBConnectionManager.cpp)

add_executable(MySQLTest ${SOURCE_FILES})

find_package(Boost COMPONENTS REQUIRED)

link_directories(C:/mysql_connector/lib)

target_link_libraries(MySQLTest "C:/mysql_connector/lib/mysqlcppconn.dll"  "C:/Program Files/MySQL/MySQL Server 5.7/lib/libmysql.dll" "C:/mysql_connector/lib/libmysqlclient.dll.a" "C:/mysql_connector/lib/libmysqlclient_r.dll.a" ${Boost_LIBRARY_DIR})

Remarquez comment j'ai lié les bibliothèques libmysqlclient.dll.a et libmysqlclient_r.dll.a qui correspond à ce que j'ai reçu de Cygwin. 

Lorsque j'exécute l'application maintenant, l'instance du pilote est correctement installée et la console est émise.

Starting DBConnectionManaged - Updated
Getting driver instance
Got driver instance

Mais quand j'essaye de me connecter avec driver-> connect je reçois alors l'erreur suivante

0 [main] MySQLTest 2976 C:\Users\Chris\.CLion2016.2\system\cmake\generated\MySQLTest-8702ae13\8702ae13\Debug\MySQLTest.exe: *** fatal error - Internal error: TP_NUM_C_BUFS too small: 50

Lorsque je le mets dans le débogueur, il échoue sur le pilote -> connecter avec

gdb: unknown target exception 0xe06d7363 at 0x7fff11347788

Program received signal ?, Unknown signal.
0x00007fff11347788 in RaiseException () from /cygdrive/c/WINDOWS/System32/KERNELBASE.dll

Mise à jour 2

Tout ce que j'ai lu indique que les fichiers binaires du connecteur mysql devraient fonctionner correctement, alors j'ai recommencé. Ci-dessous se trouve maintenant le contenu de mon fichier cmake 

cmake_minimum_required(VERSION 3.6)
project(MySQLTest)


#add_compile_options("-v")

SET(GCC_COVERAGE_LINK_FLAGS )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(BOOST_INCLUDE_DIR C:/boost_1_61_0)
set(BOOST_LIBRARY_DIR C:/boost_1_61_0/libs)

include_directories("C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/include" "C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/include/cppconn" ${BOOST_INCLUDE_DIR})


set(SOURCE_FILES main.cpp DBConnectionManager.cpp)

add_executable(MySQLTest ${SOURCE_FILES})

find_package(Boost COMPONENTS REQUIRED)

link_directories(C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/lib/opt)

target_link_libraries(MySQLTest C:/Program\ Files/MySQL/MySQL\ Connector\ C++\ 1.1.7/lib/opt/mysqlcppconn.lib ${Boost_LIBRARY_DIR})

Maintenant, quand je compile, j'obtiens l'erreur d'origine

C:/Program Files/MySQL/MySQL Connector C++ 1.1.7/lib/opt/mysqlcppconn.lib(mysqlcppconn.dll.b):(.text+0x2): relocation truncated to fit: R_X86_64_32 against symbol `__imp_get_driver_instance' defined in .idata$5 section in C:/Program Files/MySQL/MySQL Connector C++ 1.1.7/lib/opt/mysqlcppconn.lib(mysqlcppconn.dll.b)

Cela me semble être comme si mon application compilait en 32 bits au lieu de 64 bits. En guise de test, j'ai exécuté le code suivant:

cout << "Int size is: " << sizeof(int) << endl;

Le code ci-dessus affiche 4 (ne devrait pas être 8 s'il a été compilé en 64 bits). 

Si ma pensée est correcte, pourquoi ne la compile-t-elle pas en 64 bits? J'ai essayé de définir l'indicateur de compilation -m64, mais cela ne fait aucune différence. J'ai également installé le Cygwinx64 utilisé par CLion. 

17
Boardy

Vous pouvez utiliser MySQL Connector C++

Voici comment configurer en utilisant Cmake

cmake_minimum_required(VERSION 3.7)

project(projectname)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

Inclut les répertoires où vous avez extrait mysql-connector-cpp - download

include_directories(/usr/local/include/mysql-connector-cpp/include)

Crée une variable cmake contenant les fichiers sources du projet

set(SOURCE_FILES main.cpp)

Créez votre exécutable

add_executable(projectname ${SOURCE_FILES})

Lien après la création d'un exécutable

target_link_libraries(projectname mysqlcppconn)

Votre CMakeList devrait au moins avoir ceci ou ressembler à ceci dans cet ordre

cmake_minimum_required(VERSION 3.7)
project(projectname)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(/usr/local/include/mysql-connector-cpp/include)
set(SOURCE_FILES main.cpp)
add_executable(projectname ${SOURCE_FILES})
target_link_libraries(projectname mysqlcppconn)
5
Victor Mwenda

Vous pouvez utiliser la bibliothèque mysql ++ pour vous connecter à mysql à partir de c ++.
Pour cette installation, mysql ++,
( Ubuntu )

Sudo apt-get install mysql-server mysql-client
Sudo apt-get install libmysqlclient-dev libmysql++-dev libmysqlcppconn-dev

( Mac )

brew install mysql++

inclure la bibliothèque en ajoutant,

/usr/include/mysql++
/usr/include/mysql

et ajouter des linkers,

-lmysqlpp -lmysqlclient

Exemple de code ,

#include <iostream>
#include <string>
#include <mysql++.h>
#include <mysql.h>

#define dbname "dbname"
#define server "localhost"
#define user "username"
#define pass "password"

using namespace std;
using namespace mysqlpp;

int main() {
    Connection con(true);
    try {
        con.connect(dbname, server, user, pass);
        cout << "Connected to database\n";
        string s = "SELECT * FROM mirrors_mee WHERE id=1";
        Query q = con.query(s);
        StoreQueryResult sq = q.store();
        StoreQueryResult::iterator it;
        it = sq.begin();
        while (it != sq.end()) {
            Row row = *it;
            cout << row[5] << " " << row[6] << " " << row[7] << endl;
            it++;
        }
    } catch (Exception &e) {
        cout << e.what() << endl;
    }
    return 0;
}

Vous obtiendrez une documentation complète de la bibliothèque ici .

1
Sakib Sami