由于 MySql 连接器 C++,如何修复未解析的外部符号?
Posted
技术标签:
【中文标题】由于 MySql 连接器 C++,如何修复未解析的外部符号?【英文标题】:How to fix unresolved external symbol due to MySql Connector C++? 【发布时间】:2010-12-17 11:09:08 【问题描述】:我遵循了本教程http://blog.ulf-wendel.de/?p=215#hello。我在 Visual C++ 2008 和 Visual C++ 2010 上都试过了。无论是静态的还是动态的,编译器都给了我完全相同的错误消息:
error LNK2001: unresolved external symbol _get_driver_instance
以前有人遇到过这个问题吗?
更新: + 附加依赖项:mysqlcppconn.lib + 其他包含目录:C:\Program Files\MySQL\MySQL Connector C++ 1.0.5\include + 附加库目录:C:\Program Files\MySQL\MySQL Connector C++ 1.0.5\lib\opt
另一个更新: 在 get_driver_instance() 上点击 F12 链接到:
class CPPCONN_PUBLIC_FUNC Driver
protected:
virtual ~Driver()
public:
// Attempts to make a database connection to the given URL.
virtual Connection * connect(const std::string& hostName, const std::string& userName, const std::string& password) = 0;
virtual Connection * connect(std::map< std::string, ConnectPropertyVal > & options) = 0;
virtual int getMajorVersion() = 0;
virtual int getMinorVersion() = 0;
virtual int getPatchVersion() = 0;
virtual const std::string & getName() = 0;
;
/* namespace sql */
extern "C"
CPPCONN_PUBLIC_FUNC sql::Driver *get_driver_instance();
显然,该函数存在,但链接器找不到它。
代码sn-p:
#include <iostream>
#include <sstream>
#include <memory>
#include <string>
#include <stdexcept>
using namespace std;
#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()
try
sql::Driver *driver;
sql::Connection *conn;
sql::Statement *stmt;
sql::ResultSet *res;
driver = get_driver_instance();
conn = driver->connect( "http://localhost/chandb", "root", "chan" );
stmt = conn->createStatement();
res = stmt->executeQuery( "select * from another" );
while( res->next() )
cout << "id = " << res->getInt( "Id" );
cout << "id = " << res->getInt( "GoldValue" );
cout << "id = " << res->getString( "Model" );
delete conn;
delete stmt;
delete res;
std::cout << "This is it";
catch( sql::SQLException e )
cout << e.what();
谢谢, 陈
【问题讨论】:
你是如何链接你的程序的? 可能链接的时候没有加一些库。 我按照上面的教程至少做了 3 次。我在调试和发布模式下都非常仔细地检查过。我真的找不到我错过的地方:( 您是否尝试同时进行动态和静态链接?你应该只做一个。本教程显示两者都做,你可能已经做过两次了。 我做了一次,然后为另一个创建了另一个项目。谢谢! 【参考方案1】:根据MySQL 5.1 Reference Manual,如果您使用的是 MySQL 连接器 C++ 的 1.1 版:
“get_driver_instance() 现在仅在动态库构建中可用 - 静态构建不可用
有这个符号。这样做是为了适应使用 LoadLibrary 或 dlopen 加载 DLL。如果您不使用 CMake 构建源代码,如果您正在动态加载并希望使用 get_driver_instance() 入口点,则需要定义 mysqlcppconn_EXPORTS。"
如果我正确理解前面的注释,您必须使用动态构建并定义mysqlcppconn_EXPORTS
。
【讨论】:
我不确定你定义 mysqlcppconn_EXPORTS 是什么意思。所以我做了:#define mysqlcppconn_EXPORTS,我仍然有同样的错误。 @Chan:试试这个:项目/属性/C++/预处理器/预处理器定义中的mysqlcppconn_EXPORTS,重建你的代码。 非常感谢您的快速回复。但是,我做到了,它仍然产生相同的错误:(! 它对我也不起作用。你找到解决办法了吗?【参考方案2】:如果使用静态链接,需要在Project / Properties / C++ / Preprocessor / Preprocessor Definitions
中设置CPPCONN_PUBLIC_FUNC=
【讨论】:
【参考方案3】:我在使用 c++/Sql 连接器时遇到了同样的错误。 花了一整天后,我通过使用 32 位 libmysql.dll、32 位 libmysqlcppcon.lib 和 32 位 libmysqlcppcon.dll 解决了这个问题(使用动态绑定,因为驱动程序实例创建仅在 libmysqlcppcon.lib 的动态库中可用)
我找到了很好的链接,可以解释所有内容以及工作代码。我认为如果他们坚持同样的问题,这将对其他人有所帮助。
http://r3dux.org/2010/11/how-to-use-mysql-connectorc-to-connect-to-a-mysql-database-in-windows/
【讨论】:
请注意,您应该在此处或此站点上发布答案的基本部分,否则您的帖子可能会被删除 See the FAQ where it mentions answers that are 'barely more than a link'. 如果您愿意,您仍然可以包含链接,但只能作为“参考'。答案应该是独立的,不需要链接。【参考方案4】:错误 LNK2001:未解决的外部 符号_get_driver_instance
该错误消息基本上意味着链接器无法在任何地方找到函数 get_driver_instance,例如。它不在编译单元的任何目标文件中,不在静态 .lib 库或导入库中。如果库中的重整名称与链接器期望找到的名称不匹配完全,也会发生这种情况。例如。库是使用不同的调用约定等构建的。
我建议您查看项目中使用的最终命令行,并在此处更新您的帖子以进行编译和链接。其次,确保您链接的 mysql 库具有该功能。我相信 vs 中有一个命令行工具用于转储和查看静态库的内容。
如果您要链接 mysql 的动态 dll 版本,请确保导入库包含缺少的引用符号。此外,您可以使用 PE 查看器打开 dll 并查看它的导出表,以验证该函数确实存在并且可见。
编辑:根据this post,函数get_driver_instance 应该在'mysqlcppconn.lib' 某处。您确定该文件已正确链接吗?
【讨论】:
我遇到了与上述相同的问题,并通过在链接的包含库中包含 mysqlcppconn 来解决它【参考方案5】:我读过你提到的那篇文章。 static 编译有这一行:如前所述,您需要链接“mysqlcppconn-static.lib”和“libmysql.lib”。
既然你没有提到这是你的问题,你试过这个吗?
另外,在一个论坛上,我读到了这个(对于 eclips)“你必须在源代码中有这个”:
#include "mysql_driver.h"
#include "mysql_connection.h"
using namespace sql::mysql;
不管怎样,祝你好运!
【讨论】:
【参考方案6】:我不知道您是否已经决定使用 这个 MySQL 连接器/驱动程序包,但是如果这导致看似不言而喻的话,有许多强大的数据库包装器可以免费或几乎免费使用让你头疼。
实际上,当我之前将 QT 数据库对象用于数据模型项目时,我对它们印象深刻。 The QT framework 在 LGPL 下获得许可,并且还提供商业版本,是一组非常通用的跨平台库。 QtSql 对象为包括 MySql、SQLServer、Postgres、ODBC 等在内的许多数据库提供了一致的接口,并且能够替换您自己的驱动程序,并且仍然对 C++ 中的所有内容使用相同的接口
其他一些值得注意的选项:
SQLApi++
MySQL++
不要试图像推销员或其他任何人那样出人头地,我与其中任何一个都没有任何关系,但有时货比三家并找到更适合您需求的东西永远不会有坏处。
【讨论】:
非常感谢!我想使用这个连接器的原因是因为它提供了简单而干净的 API;另外我已经使用过 J-Connector,所以我试图找到类似的东西。虽然我只学了 4 个月的 Java,但我真的很喜欢 J-Connector 设计。其实Connector C++的API和J-Connector基本一样,只是安装部分有点不同。在 Eclipse 中使用它时,我只需要添加一个外部 jar,就完成了! 这相当于一个仅链接的答案(因为它只链接到其他库,其他一切都是胡扯)。【参考方案7】:我在 64 位操作系统上使用 mysql 服务器和连接器/c++ 的 32 位版本解决了问题。 我认为问题在于 boost 库,但我不确定。
【讨论】:
这也为我解决了这个问题。虽然当您开始使用 32 位版本时,会突然出现一大堆错误,您必须参考 Boost 标头。【参考方案8】:我花了几个小时试图解决与您完全相同的问题。我终于自己发现了问题。我下载了 64 位版本的 MySQL/SQL 连接器,并按照 MySQL.com 中的教程设置 win32 控制台项目的属性,并收到上述错误消息。这是因为本教程正在教构建一个 32 位程序。在我更改构建 X64 代码的发布版本后,问题就解决了。 确保您的库是 32 位或 64 位,然后相应地配置您的 Visual Studio(在配置管理器中)。
【讨论】:
这是正确答案。 @Chan 会将其标记为显示在顶部。这将为面临这个问题的人节省大量时间。谢谢@ngamc! @RenatoAloi 这对你来说可能是正确的答案,但对其他人来说可能不是。【参考方案9】:你好,同样的问题,我已经搜索并找到了我的解决方案,我在我的本地计算机上给你我的路径,但你可以把所有你想要的地方,这只是我的个人笔记:
目标是在您的计算机上编译 mysql cpp 连接器,让 lib 在您编译时可以在您的计算机上运行。
依赖关系:
克隆(递归地使用子模块,拥有文件夹 jdbc)主分支上的 repo(当我写这篇文章时,对我来说与 8.0.27 相同)的 mysql cpp 连接器 源代码的 windows on github:
https://github.com/mysql/mysql-connector-cpp/tree/master 或者如果你没有 git,你可以手动下载 zip:mysql-connector-c++-8.0.27-src.zip:https://dev.mysql.com/downloads/connector/cpp/ 并通过单击此页面上的 jdbc 文件夹手动下载 jdbc:https://github.com/mysql/mysql-connector-cpp/tree/master 并且下载的jdbc必须解压并重命名为“jdbc”,并放入mysql cpp连接器文件夹中为windows下载mysql服务器:
选择:Windows(x86、64 位)、ZIP 存档
版本:8.0.27
大小:209.4M
网址:https://dev.mysql.com/downloads/mysql/
文件名:mysql-8.0.27-winx64
把mysql-8.0.27-winx64放到C:\Users\
\Downloads\mysql-8.0.27-winx64 下载openssl(Win64 OpenSSL v1.1.1m):
二进制安装程序 msi:https://slproweb.com/products/Win32OpenSSL.html 它不是官方的:/ 但它工作(并且它也被这个网站链接:https://wiki.openssl.org/index.php/Binaries),我失败并放弃从源代码构建) 在此处安装 openssl:E:\OpenSSL-Win64 不幸的是,3.0.1 版不适用于构建 cpp 连接器(或者我的错误?)下载提升:https://www.boost.org/users/download/
解压缩并放在这里:E:\boost_1_78_0
配置:
对于配置,您必须具有此文件夹架构:
. Parent Folder (for me it's E:\MySql)
|
|\
| \
| . _SOURCE (renamed mysql cpp connector repo)
| |
| .
| .
| .
| |
| |\
| | \
| | . jdbc (jdbc submodule)
| .
| .
| .
|
|\
| \
| . _BUILD
\
\
. _INSTALL
如果您在接下来的命令中有错误,则使用此文件夹架构,您的源将不会被修改,您只需删除 _BUILD 和 _INSTALL 文件夹的包含即可重新启动
在 E:\MySql 中打开 powershell 并启动 cmd:cmake .\_SOURCE\ -B .\_BUILD\ -D CMAKE_INSTALL_PREFIX=.\_INSTALL -D CMAKE_BUILD_TYPE=Debug -D WITH_SSL="E:\OpenSSL-Win64" -D BUILD_STATIC=OFF -D WITH_JDBC=ON -D WITH_MYSQL="C:\Users\\Downloads\mysql-8.0.27-winx64" -D WITH_BOOST="E:\boost_1_78_0" -D MYSQLCLIENT_STATIC_BINDING=OFF -D MYSQLCLIENT_STATIC_LINKING=OFF -G "Visual Studio 16" -一个“x64”
输出的最后几行必须是这样的:-- 配置完成
-- 生成完成
-- 构建文件已写入:Your-Build-Path/_BUILD
建筑:
启动命令:cmake --build .\_BUILD\
可能有很多致命错误:
找不到mysql 找不到提升 openssl 未找到 openssl 坏版本(需要 1.1.1) 选项之间没有兼容的选项值 忘记选项,如果是这种情况,请尝试使用他的默认值添加选项如果您有错误,请检查您的路径依赖项
有一些不是致命的警告:
“is_same”测试不起作用 找不到文件 sys/endiand.h 找不到文件 sys/byteorder.h当输出显示“查看日志文件 output.log 和 errors.log”时,您在某些地方遇到了致命错误,但可能(可能)不要在警告和日志文件上浪费时间......并且查看输出的所有行,因为对我来说,致命错误没有列在日志文件中,而是列在输出中(可能不适合你,我不知道)
安装:
cmake --install .\_BUILD\ --config 调试
结束:
在文件夹中:E:\MYSQL\_INSTALL\lib64 有动态库
在文件夹中:E:\MYSQL\_INSTALL\lib64\vs14 有静态库
和 E:\MYSQL\_INSTALL\lib64\vs14\mysqlcppconn.lib 将包含“get_driver_instance”函数以使用 mysql cpp 连接器等... 如果你想用 7zip 打开 mysqlcppconn.lib,右键单击,打开存档,打开 1.txt 和 2.txt,然后 CTRL+F 你的函数
注意事项:
您不能在 Debug 中进行配置 (-D CMAKE_BUILD_TYPE=Release),否则第一个 cmake cmd 将创建一个 Visual Studio 项目 (E:\MYSQL\_BUILD\jdbc\connector-jdbc-deps.vcxproj),其中包含未知链接库(MYSQLLIB-NOTFOUND-DEBUG),cmake 构建 cmd 将失败
在我的 Visual Studio 项目中,我链接了两个静态库,并且我复制了我的 exe 旁边的两个动态库,这对我有用
版本-ARCH:
software | version | arch |
---|---|---|
windows pro | 10 | x64 |
cmake | 3.22.1 | x64 |
Microsoft Visual Studio Community 2019 | 16.11.8 | x64 |
Microsoft .NET Framework | 4.8.04084 | x64 |
openssl | v1.1.1m | x64 |
boost | 1.78.0 | cross-arch ? |
mysql server | 8.0.27 | x64 |
mysql cpp connector | 8.0.27 | x64 |
【讨论】:
以上是关于由于 MySql 连接器 C++,如何修复未解析的外部符号?的主要内容,如果未能解决你的问题,请参考以下文章