创建 C++ Redis 模块 - “不导出 RedisModule_OnLoad() 符号" [英] Creating C++ Redis Module - "does not export RedisModule_OnLoad() symbol"

查看:135
本文介绍了创建 C++ Redis 模块 - “不导出 RedisModule_OnLoad() 符号"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在加载 Redis 模块时遇到了一些问题.我只是从 https://redis.io/topics/modules-intro 复制示例,但我把它剥离了.

I am having some trouble loading my Redis module. I am just copying the example from https://redis.io/topics/modules-intro, but I stripped it down.

#include "redismodule.h"
#include <stdlib.h>

int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    if (RedisModule_Init(ctx,"avromodule",1,REDISMODULE_APIVER_1)
        == REDISMODULE_ERR) return REDISMODULE_ERR;


    return REDISMODULE_OK;
}

这是保存在 avromodule.cpp 中.我使用以下内容编译它:

This is saved in avromodule.cpp. I compile it using the following:

g++ -shared -fPIC -o avromodule.so avromodule.cpp

然后我转到 Redis CLI 并尝试加载模块.

Then I go over to the Redis CLI and try to load the module.

10.XXX.XXX.XXX:7004> module load /path/to/module/avromodule.so
(error) ERR Error loading the extension. Please check the server logs.

服务器日志给我以下错误:

The server logs give me the following error:

159392:M 17 May 10:21:19.773 # Module /path/to/module/avromodule.so does not export RedisModule_OnLoad() symbol. Module not loaded.

上述错误对我来说毫无意义,因为我使用nm"命令得到以下输出:

The above error makes no sense to me, because I get the following output using the 'nm' command:

$ nm -CD avromodule.so | grep " T "
0000000000003622 T RedisModule_OnLoad(RedisModuleCtx*, RedisModuleString**, int)
000000000000366c T _fini
0000000000002878 T _init

有人知道这里可能出了什么问题吗?我知道我使用的是 C++,而不是推荐的 C,但这应该仍然有效.

Does anyone have a clue what could be going wrong here? I know that I am using C++ as opposed to the recommended C, but this should still work AFAIK.

推荐答案

发生这种情况是因为 RedisModule_OnLoad 正在获取 名称被您的 C++ 编译器破坏.

This is happening because RedisModule_OnLoad is getting name mangled by your C++ compiler.

RedisModule_OnLoad 正在被 GCC 重命名为 __Z18RedisModule_OnLoadP14RedisModuleCtxPP17RedisModuleStringi,因此 Redis 无法找到它正在寻找的导出符号.

RedisModule_OnLoad is getting re-named to to __Z18RedisModule_OnLoadP14RedisModuleCtxPP17RedisModuleStringi by GCC, so Redis is unable to find the exported symbol it is looking for.

$ nm avromodule.so | grep OnLoad                   
0000000000000970 T __Z18RedisModule_OnLoadP14RedisModuleCtxPP17RedisModuleStringi

您可以使用 extern "C" 指令来确保导出的符号保持未损坏.

You can use the extern "C" directive to ensure your exported symbols remain un-mangled.

#include "redismodule.h"
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    if (RedisModule_Init(ctx,"avromodule",1,REDISMODULE_APIVER_1)
        == REDISMODULE_ERR) return REDISMODULE_ERR;


    return REDISMODULE_OK;
}

#ifdef __cplusplus
}
#endif

这会导致导出未损坏的符号

Which results in an un-mangled symbol getting exported

nm avromodule.so | grep OnLoad                   
0000000000000970 T _RedisModule_OnLoad

这篇关于创建 C++ Redis 模块 - “不导出 RedisModule_OnLoad() 符号"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆