Создание модуля C ++ Redis - «не экспортируется символ RedisModule_OnLoad ()» - PullRequest
0 голосов
/ 17 мая 2018

У меня проблемы с загрузкой модуля 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 и пытаюсь загрузить модуль.

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.

1 Ответ

0 голосов
/ 31 октября 2018

Это происходит потому, что RedisModule_OnLoad получает имя, искаженное вашим компилятором C ++.

GCC переименовывает

RedisModule_OnLoad в __Z18RedisModule_OnLoadP14RedisModuleCtxPP17RedisModuleStringi, поэтому Redis не может найти экспортированный символ, который ищет.

$ nm avromodule.so | grep OnLoad                   
0000000000000970 T __Z18RedisModule_OnLoadP14RedisModuleCtxPP17RedisModuleStringi

Вы можете использовать директиву 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
...