C++ / mysql 连接器 - undefined reference to get_driver_instance - 已经尝试了易用的方法

23

这个问题以前已经被问过了... 我尝试了之前回答中提到的所有方法。我的设置非常简单,所以这不应该很难。

我只想使用C++编写针对mysql的程序。我的源代码直接从这里的“hello world”类型示例中获取:

http://dev.mysql.com/doc/refman/5.1/en/connector-cpp-examples-complete-example-1.html

我在Ubuntu 12.10上。我正在尝试:

g++ -Wall -o firsttry_prog -I/usr/include/mysqlcppconn -I/usr/local/boost_1_53_0  -L/usr/lib/x86_64-linux-gnu -l:libmysqlclient_r.so.18 -L/usr/lib/mysqlcppconn -lmysqlcppconn  firsttry.cpp

如果我使用-c选项,它会进行编译,但无法构建,给出了臭名昭著的错误提示:
/tmp/ccn768hj.o: In function `main':
firsttry.cpp:(.text+0x3a): undefined reference to `get_driver_instance'

一些细节:
  • 'firsttry.cpp' 只是我给源代码文件取的名字,完全按照官方示例
  • 正如您所看到的,我正在链接 mysqlclient 库和 mysqlcppconn 库。许多时候,当此问题以前被问到时,答案就是要链接它们。
  • 其他一些历史性的答案表明样例源代码是错误的,并且需要将相关函数放在 sql::mysql 命名空间中等。我相信源代码是正确的。再次强调,它可以编译,而更改源代码中的命名空间似乎只会使情况变得更糟。
感谢您提供的任何帮助。

1
那个-l:libmysqlclient_r.so.18是什么?不应该是-lmysqlclient_r吗? - Alexander Shukaev
谢谢Haroogan。我从链接中了解到-l: business,我相信这只是一种在传统命名风格的符号链接不存在时指定完整文件名的方式,就像对我而言一样。所以如果我尝试-lmysqlclient_r,它会告诉我找不到-lmysqlclient_r。根据您的反馈,我继续制作了符号链接,现在我可以使用-lmysqlclient_r...但我仍然遇到关于“get_driver_instance”的相同错误。还有其他想法吗? - Ray in NY
尝试先将 firsttry.cpp 编译为 firsttry.o,然后将其链接到那些 MySQL 库中以生成可执行文件。即像这样:g++ -Wall -I/usr/include/mysqlcppconn -I/usr/local/boost_1_53_0 -o firsttry.o firsttry.cppg++ firsttry.o -L/usr/lib/x86_64-linux-gnu -l:libmysqlclient_r.so.18 -L/usr/lib/mysqlcppconn -lmysqlcppconn -o firsttry - Alexander Shukaev
很有趣...正如我上面所提到的,它仍然可以编译成.o文件没有问题。但是当我尝试链接它时(您的第二个命令,尽管我现在已经尝试了几个变体,但结果相同),我会得到几十个错误,全部都是这种形式:/usr/lib/mysqlcppconn/libmysqlcppconn.so: undefined reference to mysql_stmt_execute@libmysqlclient_18'等等,所有未定义的引用都在libmysqlcppconn中...为什么会这样呢? - Ray in NY
更改顺序:-l:libmysqlclient_r.so.18 -lmysqlcppconn - Alexander Shukaev
显示剩余4条评论
4个回答

33

现在我已经遇到这个问题一个星期了,我也变得非常沮丧。刚才终于成功构建了一个仅用于登录mysql的程序,我实在是开心得尖叫了。以下是我的做法,希望对你有所帮助。

我首先从源代码编译了c++连接库,但过了一段时间后,我认为可能是我的操作有误,于是我使用apt获得了它:

sudo apt-get install  libmysqlcppconn-dev

这里是我的简单测试程序源文件"tester.cpp"

#include <stdlib.h>
#include <iostream>
#include <mysql_connection.h>
#include <driver.h>
#include <exception.h>
#include <resultset.h>
#include <statement.h>

using namespace sql;
int main(void){
  sql::Driver *driver;
  sql::Connection *con;

  driver = get_driver_instance();
  con = driver->connect("tcp://127.0.0.1:3306","root","YOURPASSWORD");
  
  return 0;
}

最后是 g++ 编译命令:

g++ -Wall -I/usr/include/cppconn -o testapp tester.cpp -L/usr/lib -lmysqlcppconn

这对我有用,我希望它能帮助你解决问题!


1
是的-那个方法行得通了!太神奇了,谢谢。具体来说,行得通的方法是通过apt-get install获取库,而不是尝试从源代码构建它(对你来说没有用),甚至不是从MySQL网站下载库并将它们放在自己的文件夹中(对我来说也没用)。非常感谢! - Ray in NY
虽然这个问题已经解决了,但我仍然对我一开始做错了什么感到好奇。尽管我对C++有些生疏并且对Linux有点陌生,所以可能这是一个真正的新手错误。我的最佳猜测是它必须与目录位置有关...... apt-get installmysqlcppconn 直接放在 /usr/lib 的根目录下,而我将其放在了子目录 etc 中。但只要我在构建程序时指定了完整路径,这应该没问题,是吗?即使在编译阶段,它也告诉我需要同时指定 Boost 等... - Ray in NY
很棒的解决方案,即使我需要先删除现有的libmysqlcppconn-dev,然后按照你说的做。经过两天的努力后,它运行得非常好!我不知道MySQL人员在他们的文档中留下了什么。 - Catty
@RayinNY在将库下载并放置在相应文件夹后,你是否运行了ldconfig命令? - Chandranshu
非常感谢 :) 我所需要的只是最后一行 :P (编译) - Severus Tux
兄弟,我无法形容这有多令人沮丧。非常感谢你在这里的注释! - Phyllis Sutherland

9

对我来说,只需要交换最后两个参数的顺序就可以解决这个问题。我不知道为什么,但如果我在源文件之后指定-lmysqlcppconn选项,链接器就能找到get_driver_instance函数。

g++ -Wall -o firsttry_prog -I/usr/include/mysqlcppconn -L/usr/lib/mysqlcppconn firsttry.cpp -lmysqlcppconn

请注意,我删除了以下选项,因为我认为它们是多余的。
-I/usr/local/boost_1_53_0  -L/usr/lib/x86_64-linux-gnu -l:libmysqlclient_r.so.18

1
是的,这对我也起作用了,就像描述的那样,将链接标志移到命令的末尾而不删除任何其他标志 - 有人明白吗? - Brizee
我也是!非常让人恼火,但真的很高兴我解决了它,多亏了你!但既然它现在可以正常工作了,就像@Brizee所问的,有没有人知道为什么需要这样做?如果有人能指出一些文档片段,那就太好了。 - DanielM

7

如果您跟我一样健忘,没有在CMakeLists.txt中链接库:

target_link_libraries(<target> mysqlcppconn)

1
你好,<target>应该是什么?我也在使用CMakeLists.txt,你的答案很可能能帮到我。 - Haohan Wang
目标是您在add_executable(myproj)之后使用的名称。在这种情况下,名称为myproj。https://schneide.wordpress.com/2016/04/08/modern-cmake-with-target_link_libraries/ - user584583

2
如果所有路径都已经包含在参数 -I 中,您可以像这样编译来查看是否存在问题:
g++ -g  -o0  -I/usr/local/include -I/usr/local/boost/include -c main.cpp -o main.o
g++ -g  -o0 -L/usr/local/lib -L/usr/local/mysql/lib -lmysqlcppconn  main.o  -o test  

问题将会出现:
main.o: In function `main':
/home/huangxw/workspace/public/soal/test/main.cpp:165: undefined reference to `get_driver_instance'
collect2: ld returned 1 exit status

现在您需要调整-lmysqlcppconnmain.o的顺序:
g++ -g  -o0  -I/usr/local/include -I/usr/local/boost/include -c main.cpp -o main.o
g++ -g  -o0 -L/usr/local/lib -L/usr/local/mysql/lib main.o  -o test  -lmysqlcppconn

就是这样了!原因很简单。您可以通过网络查询或要求我详细说明。


1
我对两个问题感到困惑。1)为什么这会有所不同,2)我应该如何使用autotools/automake指定它在我的“main.o”之后出现? - Discordanian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接