【问题标题】:Embedded MariaDB C/C++ API嵌入式 MariaDB C/C++ API
【发布时间】:2018-02-02 10:14:50
【问题描述】:

我正在尝试进行嵌入式 MariaDB(即不连接到正在运行的服务器)设置,但我发现任何示例都无法正常工作。

我最近的例子来自这篇帖子https://stackoverflow.com/a/24548826/400048

当应用程序运行时,它会产生: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 文档https://mariadb.com/kb/en/library/embedded-mariadb-interface/ 对此没有太大帮助。

为方便起见,StackOverflow 帖子中的代码如下:

#include <my_global.h>
#include <mysql.h>

int main(int argc, char **argv) {  
    static char *server_options[] = {
                                   "mysql_test", // An unused string 
                                    "--datadir=/tmp/mysql_embedded_data", // Your data dir
                                    NULL };
    int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;

    static char *server_groups[] = { "libmysqld_server",
                                     "libmysqld_client", NULL };


    // Init MySQL lib and connection    
    mysql_library_init(num_elements, server_options, server_groups);
    MYSQL *con = mysql_init(NULL);

    if (con == NULL) {
        fprintf(stderr, "%s\n", mysql_error(con));
        exit(1);
    }

    mysql_options(con, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client");
    mysql_options(con, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);

    // Connect to no host/port -> Embedded mode
    if (mysql_real_connect(con, NULL, NULL, NULL, NULL, 0, NULL, 0) == NULL) {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Create a sample empty DB, named "aNewDatabase"
    if (mysql_query(con, "CREATE DATABASE aNewDatabase")) {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Close connection
    mysql_close(con);
    exit(0);
}

我粗略地看了一下https://github.com/MariaDB/server,但不知道该去哪里寻找……或者实际上我在寻找什么。 如何让嵌入式 mariadb 运行? 我在 Mac OS High Sierra 上运行,MariaDB 使用brew install mariadb --with-embedded 安装。

更新:

我很确定我链接到了正确的库。

ls /usr/local/lib | grep maria

FIND_LIBRARY(mariadb mariadb)
MESSAGE(FATAL_ERROR "BOOM ${mariadb}")

其中的输出是: BOOM /usr/local/lib/libmariadb.dylib

更新 2

我现在链接到以下内容。请注意,我从 libmysqld 开始并添加了库,直到所有链接错误都消失了。这里的问题是我可能没有所有正确的库或版本。

TARGET_LINK_LIBRARIES(sql_fn /usr/local/lib/libmysqld.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/openssl/lib/libcrypto.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/openssl/lib/libssl.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/bzip2/lib/libbz2.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/lib/liblz4.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/zlib/lib/libz.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/xz/lib/liblzma.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/lib/libsnappy.a)

它现在编译但退出代码 6

Process finished with exit code 6 查看https://stackoverflow.com/a/7495907/400048,如果它指向相同的东西/仍然正确,那么退出代码6 表示EX_ILLEGAL_TABLE 6,不幸的是我不知道那会是什么表。传入的 mysql_test 和 datadir 字符串是有效的标识符/路径。

【问题讨论】:

  • 一个问题,/tmp/mysql.sock 是否存在...如果不存在,则尝试使用touch /tmp/mysql.sock 创建一个新的,然后尝试再次运行您的应用程序。
  • 创建文件确实会将错误消息从:Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 更改为 Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)。恐怕没什么别的了。
  • @zcourts:你是在链接 libmysqlclient.a 还是 libmysqld.a ?
  • libmariadb.dylib,如果文件名可以通过,则不是客户端。
  • @zcourts:好吧,我们在这个评论线程上的空间即将用完(cmets 不适合扩展讨论)。在调试器中设置断点并确保已创建连接。如果是,那么您就知道服务器是实时的,并且问题在于创建文件,这实际上取决于操作系统,而不是服务器。

标签: mysql c mariadb


【解决方案1】:

好的,首先对您的示例进行一些解释。用户正在使用 gcc 进行编译,我可以看到您正在使用 cmake。 首先 -lz 和 mysql_config --include --libmysqld-libs 是什么意思。首先是链接zlib到cmake中链接zlib你可以参考this answer,长话短说:

find_package( ZLIB REQUIRED )
if ( ZLIB_FOUND )
    include_directories( ${ZLIB_INCLUDE_DIRS} )
    target_link_libraries( sql_fn ${ZLIB_LIBRARIES} )
endif( ZLIB_FOUND )

然后您需要 mariaDB 库,这是第二部分。 mysql_config --include --libmysqld-libs 这意味着执行命令 mysql_config --include --libmysqld-libs 将返回一个带有链接选项的字符串,所以执行命令:

$mysql_config --include --libmysqld-libs
-I/usr/local/mysql/include
-L/usr/local/mysql/lib  -lmysqld

你应该得到一个类似上面的输出。 -I 是在给定目录中查找头文件,-L 是在目录中搜索库,-l 是链接给定库,它的用途与 -lz 相同,只是您要添加 -lmysqld。

现在已经解释了所有内容,您只需要在 mysql 中包含 -I -L 和 -l 选项,但这不是一个标准库,因此您需要通过脚本包含目录和库,如 this anwer 中所述。所以长话短说,没有子弹证明,例如我的库在 /usr/local/mysql/lib 中,而你的库在 /usr/local/lib 中。既然如此,使用第二种方法会更容易。

execute_process(COMMAND mysql_config --include
    OUTPUT_VARIABLE MYSQL_INCLUDE)
execute_process(COMMAND mysql_config --libmysqld-libs
    OUTPUT_VARIABLE MYSQL_LIBS)

target_compile_options(sql_fn PUBLIC ${MYSQL_INCLUDE})
target_link_libraries(sql_fn ${MYSQL_LIBS})

这就是您需要的所有必需信息。现在我们很高兴我们有 Cmake 让我们的事情变得更容易,不是吗。 ;) 这是我的 CMakeLists.txt

cmake_minimum_required(VERSION 3.6)
project(embedded_mysql)

set(CMAKE_CXX_STANDARD 14)

set(SOURCE_FILES main.cpp)
add_executable(embedded_mysql ${SOURCE_FILES})

find_package( ZLIB REQUIRED )
if ( ZLIB_FOUND )
    include_directories( ${ZLIB_INCLUDE_DIRS} )
    target_link_libraries( embedded_mysql ${ZLIB_LIBRARIES} )
endif( ZLIB_FOUND )

execute_process(COMMAND mysql_config --include
        OUTPUT_VARIABLE MYSQL_INCLUDE)
execute_process(COMMAND mysql_config --libmysqld-libs
        OUTPUT_VARIABLE MYSQL_LIBS)

string(STRIP ${MYSQL_LIBS} MYSQL_LIBS)

target_compile_options(embedded_mysql PUBLIC ${MYSQL_INCLUDE})
target_link_libraries(embedded_mysql ${MYSQL_LIBS})

可以在github中看到代码here

【讨论】:

  • Nord,感谢您的详细回答。请问您是在哪个操作系统上试用的?它像我的示例一样构建,但仍然以代码 6 退出。在 @Mark 的最后一条评论 mysql_library_init 之后是退出发生的位置,目录是 /tmp 所以我认为这不是文件/权限问题。我的下一步将是尝试在 VM Centos/Ubuntu 等中构建,所以如果你让我知道你使用的是哪个操作系统,我会尝试使用相同的。
  • 我是在 OS X Sierra 中完成的,我不记得确切的版本,但我会在我的移动计算机上立即更新它。我将目录更改为对我的用户具有权限的目录,例如 /Users//tmp/embbeded 并且它有效。它发送一个警告,但以退出代码 0 结束。该表是在我指定的目录中创建的。我不记得我是如何安装 MariaDB 的。可能与您安装的 MariDB 有关。
  • 我也在使用 Sierra。您是否链接到实际的 MySQL 或 MariaDB?是用自制软件还是其他方式安装的?
  • 我现在记得了。我使用 MySQL 是因为在 OS X 中安装 MariaDB 很麻烦。我有“myql Ver 14.14 Distrib 5.6.23, for osx10.8 (x84_64) using EditLine wrapper”,但它应该是一样的,我检查了 MariaDB 文档。 OS X High Sierra 10.13.2.
  • 好的。我让它工作了。我浏览了我的/usr/local 并手动删除了它所依赖的所有库,并从includes 中清除了所有头文件。重建你的版本,它像以前一样以退出代码 6 失败,然后我创建了数据目录并 chmod 它(反映@ MarkBenningfield 的 cmets 然后你的版本工作了。我回去,确保目录存在并尝试了我的原始目录,这也有效. 最终我认为我安装了一个搞砸的库。在 Mark 的 cmets 之后数据目录肯定存在,我仍然得到退出代码 6。不过现在可以工作了,再次感谢!
猜你喜欢
  • 1970-01-01
  • 2013-01-30
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
相关资源
最近更新 更多