Reputation: 151
So, here am I again guys. After whole day of trying to figure out a solution for linking libmysql.lib and mysqlclient.lib, I'm thoroughly done. So, there, I decided to take another way and use convenient MySQL connector.
As 1.1.0 version of it uses boost, which I didn't have available and didn't want to take time and figure everything about, I decided to download 1.0.5.
So, I installed it, created new project, linked all necessary libraries, set additional libraries and includes (well, generally, done everything according to this manual. To test if it was working correctly, I used sample like 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();
}
}
I skipped part of the code, because it's not the point here. So, the problem with this was Application error telling about being unable to start correctly (0xc000007b). Debugging didn't quite help, as this error occurred as soon as the program runs, i.e. even if I put infinite loop at the beginning, it still crashes.
So, there I thought: "It should be some bug of this version, so I have to try newer one". After this I've gone ahead and downloaded version 1.1.0 of connector as well as boost libraries. Than created new project, set all dependencies just like with the first one, but pointing to the newer version of connector. Beside that, I've set new reference mysqlcppconn_EXPORTS. So, preparations were done and for testing purposes I've used code from MySQL site, well, generally, something like this:
/*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()
And guess what? Yup, here goes linker error again:
error LNK2001: unresolved external symbol _get_driver_instance
So please anyone tell me what am I doing wrong? It would be much appreciated.
I'll state it explicitly and write it in bold font so there won't be any answer in this manner. I've definetely set both Preferences -> C/C++ -> General -> Additional Include Directories as well as Preferences -> Linker -> General -> Additional Library Directories.
Also, I've put mysqlcppconn.lib
to Preferences -> Linker -> Additional Dependencies.
Beside, I've put mysqlcppconn.dll
and libmysql.dll
(yup, from the respective C++ Connector versions) into my project folder, do no problems with it.
Oh, and yes, I've tried both with and without CPPCONN_PUBLIC_FUNC=
key in Preprocessor Definitions - no changes occured.
It's just as I've said - with the same project preferences, version 1.0.5 of connector fails at Building stage and version 1.1.0 - at Compiling stage.
p.s. I'm using VS 2010, my OS - Windows 7 x64. Both projects and libraries are x32.
Upvotes: 4
Views: 3659
Reputation: 1481
I had the same problem "unable to start correctly (0xc000007b)" exactly. The problem was that I didn't use the correct DLL (used x86 instead of x64) even though I have installed (and re-installed) mysql for 64 bit.
I have added to PATH variable "C:\MySQL\Connector C++ 1.1.3\lib\opt" where mysqlcppconn.dll (for x64) is located. Nevertheless, in my PATH there is another directory (lua installation) which has mysqlcppconn.dll (for x86). Since the x86 directory was set before MySQL directory the x86 dll was loaded and hence "unable to start ..."
In order to avoid this I have copied mysqlcppconn.dll to my project debug directory.
Upvotes: 2
Reputation: 1836
I had the same "unable to start" problem and, after much pain, solved it. Unfortunately, your disclaimer on your first post says you've already tried my solution, but I'll post the process I used to prove to myself I had the wrong type of DLL (I initially was also sure I was using the correct bittage of DLL). If you're still super-sure you've got the right bittage of DLLs/LIBs, then head to the "debugging with process monitor" section.
My problem was that my post-build scripts were copying a DLL from the wrong location. I had spent a ton of time trying to make sure my DLL directory had the right stuff in it, but it turns out my post-build scripts weren't copying from that directory, and so were copying the x64 DLLs alongside my x86 application.
Tools: -Dependancy walker (http://www.dependencywalker.com/) -Process Monitor (http://technet.microsoft.com/en-ca/sysinternals/bb896645.aspx)
Procedure: -Make a project that compiles and runs without issues. I made a console app and pasted in the MySQL connector sample code. It is below. Note that I've used #pragma comment(lib) to include the lib, so you shouldn't even need to mess with the library includes, just the directories.
/* 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;
}
If that code doesn't work once you've got the directories set up, then you really need to double-check that the DLLs and LIBs you're using are the correct 32/64 bittage. You can use dependency walker to do that.
How to use dependency walker: 1) Drag DLL or EXE onto DepWalk window. In the ugly list of modules (window above log), find the DLL/EXE that you dragged in, and make sure that the CPU type in the CPU column is what you expect it is.
Process Monitor Debugging: If the toy code above compiled for you, then now you're talking! You've got a sample app that starts properly, and your broken-ass app that doesn't. Start process monitor, set a filter to include only your toy app, and run it. File->save that log, change the filter to your broken app's process name, then do it again with your broken app. Now you can compare what the two app runs wrt the mySQL DLLs, and maybe figure out where they're breaking. In my case, I noticed that it was loading libmysql.dll in the right spot, then hunting in other locations for it. I correctly deduced that this meant I had the wrong LibMySQL.dll. That may not be your problem, but I bet you'll get some insights with process monitor.
Upvotes: 0
Reputation: 928
Try to make a new Project and just make a simple DB Connector, i don't have windows available here so i can only show you my linux example:
The difference i can see is that you use prepared_statement, can you try it the statement and only include mysqlcppconn.dll in your linker and see if this "small-project" compiles? Maybe you have too many libraries in it, but a simple test would make it easier to identify your problem, if this solves your problem than you know that those libraries should not be included with each other.
If that doesn't work tell me and i will try to extend the answer.
Here my Includes:
#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();
}
}
Upvotes: 0