【linux C】在mysql中增加自定义的C动态库

前言

可能这是在比较极端的需求场景下才会有的解决方案:有个QT应用需要激活码(需要进行DES加密运算)才可使用,应用部署到生成环境之后,销售希望能在web页面之间操作获取。公司已有对外开放的web管理端,并且限制优先用mysql方式解决,避免使用socket方式。

我已经用C编写DES的加解密相关功能,QT已经用此功能进行激活校验,既然不让用socket通信,那么就看看mysql是否支持自定义的C库(SO动态库)。

答案当然是支持,官方名称为MYSQL UDF(方便阅读者查找),本篇的操作步骤是支持国产系统(已在欧拉系统下验证OK)。

操作步骤

1、安装mysql开发环境

(1)centos系统

复制代码
# 安装 MySQL 客户端开发库和头文件
sudo yum install -y mysql-devel

(2)欧拉系统

复制代码
sudo dnf install -y mariadb-connector-c-devel

安装完成后,在/usr/include/下可以看到mysql目录,编译mysql udf时,需要引用mysql头文件

2、创建UDF文件

比如我的DES加解密代码(文件名称为mydes.c)提供了以下两个对外可调用的加解密函数

复制代码
void DesJiaMi(const char* mingwen, char* des_code);// DES 加密函数
void DesJieMi(const char* des_code, char* des_miwen);// DES 解密函数

需要手动创建一个mydes_udf.c文件(名称不限定必须用_udf后缀,只是方便用于编译),下面是mydes_udf.c代码

复制代码
#include <mysql/mysql.h>
#include <string.h>

// 声明来自 mydes.c 的函数
extern void DesJiaMi(const char* mingwen, char* des_code);

// ========================
// 加密函数:my_jiami
// ========================

my_bool my_jiami_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
    if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
        strcpy(message, "ymore_jiami(plain_text): requires one string argument");
        return 1;
    }
    initid->maybe_null = 1;
    initid->max_length = 2048; // 支持长文本加密(每8字节→16 hex)
    return 0;
}

// 注意:无需 deinit,因为无动态内存

char* my_jiami(UDF_INIT *initid, UDF_ARGS *args, char *result,
                  unsigned long *length, char *is_null, char *error) {
    if (args->args[0] == NULL) {
        *is_null = 1;
        return NULL;
    }

    // 调用加密函数,直接写入 result
    DesJiaMi((const char*)args->args[0], result);

    // 计算实际长度(直到 \0)
    *length = strlen(result);
    
    // 确保以 \0 结尾(防御性)
    result[*length] = '\0';

    // 如果结果为空,设为 NULL
    if (*length == 0) {
        *is_null = 1;
        return NULL;
    }

    return result;
}

解密函数是一样的方法来造。

需要注意的是,在欧拉系统上编译时,会报以下错误

复制代码
error: unknown type name 'my_bool': did you mean 'Bool'?

只需要在mydes_udf.c文件的开头位置加上以下3行代码,再编译一次即可。

复制代码
#ifndef my_bool
#define my_bool char
#endif

3、编译UDF动态库

编译命令如下:

复制代码
gcc -shared -fPIC -o mydes.so mydes.c mydes_udf.c -I/usr/include/mysql -std=c99

会生成一个mydes.so动态库

4、动态库拷贝到mysql扩展目录中

把上面生成的mydes.so拷贝到l扩展目录中

复制代码
sudo cp mydes.so /usr/lib64/mysql/plugin/
sudo chmod 755 /usr/lib64/mysql/plugin/mydes.so

5、在数据库中创建加密函数

复制代码
CREATE FUNCTION my_jiami RETURNS STRING SONAME 'mydes.so';

测试看效果:

复制代码
SELECT my_jiami('helloworld');

这里要注意下,如果客户端版本比较低时,上面的测试命令返回的是BLOB,高版本是能拿到字符串的,当然也可以用以下强制方式获取到字符串

复制代码
SELECT CAST(my_jiami('helloworld') AS CHAR) AS forced_text;

如果是在调试,需要覆盖mydes.so,覆盖之前最好把自定义函数删除掉

复制代码
DROP FUNCTION IF EXISTS my_jiami;

覆盖之后,必须重启mysql服务

复制代码
sudo systemctl restart mysqld

然后再创建加密函数my_jiami

相关推荐
Doro再努力几秒前
【Linux操作系统12】Git版本控制与GDB调试:从入门到实践
linux·运维·服务器·git·vim
全栈工程师修炼指南12 分钟前
Nginx | stream content 阶段:UDP 协议四层反向代理浅析与实践
运维·网络·网络协议·nginx·udp
Lsir10110_20 分钟前
【Linux】进程信号(上半)
linux·运维·服务器
开开心心就好1 小时前
发票合并打印工具,多页布局设置实时预览
linux·运维·服务器·windows·pdf·harmonyos·1024程序员节
火车叼位1 小时前
脚本伪装:让 Python 与 Node.js 像原生 Shell 命令一样运行
运维·javascript·python
予枫的编程笔记1 小时前
【Linux进阶篇】从基础到实战:grep高亮、sed流编辑、awk分析,全场景覆盖
linux·sed·grep·awk·shell编程·文本处理三剑客·管道命令
Sheep Shaun1 小时前
揭开Linux的隐藏约定:你的第一个文件描述符为什么是3?
linux·服务器·ubuntu·文件系统·缓冲区
Tfly__2 小时前
在PX4 gazebo仿真中加入Mid360(最新)
linux·人工智能·自动驾驶·ros·无人机·px4·mid360
陈桴浮海2 小时前
【Linux&Ansible】学习笔记合集二
linux·学习·ansible
迎仔2 小时前
06-存储设备运维进阶:算力中心的存储管家
运维