我在加载Redis模块时遇到问题。我只是从https://redis.io/topics/modules- intro复制示例,但我将其剥离了下来。
#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中。我使用以下命令进行编译:
g++ -shared -fPIC -o avromodule.so avromodule.cpp
然后,我转到Redis CLI并尝试加载该模块。
10.XXX.XXX.XXX:7004> module load /path/to/module/avromodule.so (error) ERR Error loading the extension. Please check the server logs.
服务器日志给我以下错误:
159392:M 17 May 10:21:19.773 # Module /path/to/module/avromodule.so does not export RedisModule_OnLoad() symbol. Module not loaded.
上面的错误对我来说毫无意义,因为我使用’nm’命令获得了以下输出:
$ nm -CD avromodule.so | grep " T " 0000000000003622 T RedisModule_OnLoad(RedisModuleCtx*, RedisModuleString**, int) 000000000000366c T _fini 0000000000002878 T _init
有人知道这里可能出什么问题吗?我知道我使用的是C ++,而不是推荐的C,但是AFAIK仍然可以使用。
这是发生,因为RedisModule_OnLoad越来越重整名称由C ++编译器。
RedisModule_OnLoad
RedisModule_OnLoad被__Z18RedisModule_OnLoadP14RedisModuleCtxPP17RedisModuleStringiGCC 重命名为,因此Redis找不到所需的导出符号。
__Z18RedisModule_OnLoadP14RedisModuleCtxPP17RedisModuleStringi
$ nm avromodule.so | grep OnLoad 0000000000000970 T __Z18RedisModule_OnLoadP14RedisModuleCtxPP17RedisModuleStringi
您可以使用extern "C"指令来确保您导出的符号保持未破坏状态。
extern "C"
#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
导致导出未损坏的符号
nm avromodule.so | grep OnLoad 0000000000000970 T _RedisModule_OnLoad