Согласно документации MySQL ваша функция должна иметь следующий прототип:
extern "C" char *encrypt(UDF_INIT *initid, UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error);
Тогда вам следует использовать параметры result
и length
, чтобы "вернуть" вашу строку, если онаумещается в 255 байтов (согласно этой странице документации):
extern "C" char *encrypt(UDF_INIT *initid, UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error)
{
std::string str = encrypt_impl(args->args[0]);
strcpy(result, str.c_str());
*length = str.size();
return result;
}
В случае, если ваша строка не всегда умещается в 255 байтов, вам нужно выделить буфердля себя и, что более важно,
освободите его, чтобы избежать утечек памяти .Для этого вам нужно будет реализовать дополнительные функции
encrypt_init
и
encrypt_deinit
, как описано
здесь , и определить структуру данных, которую вы будете использовать для совместного использования ресурса всеми тремя функциями:
struct EncryptData
{
std::string encryptedStr;
};
extern "C" bool encrypt_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
/* Use non-throwing allocation because there is no one to catch the exception */
initid->ptr = (char *) new (std::nothrow) EncryptData();
/* Return false if allocation failed */
if (!initid->ptr)
return false;
return true;
}
extern "C" void encrypt_deinit(UDF_INIT *initid)
{
delete (EncryptData *) initid->ptr;
}
extern "C" char *encrypt(UDF_INIT *initid, UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error)
{
EncryptData *data = (EncryptData *) initid->ptr;
data->encryptedStr = encrypt_impl(args->args[0]);
/* Can't return c_str() here, since the return type is non-const */
return &data->encryptedStr[0];
}
Вы также можете использовать initid->ptr
для самого строкового буфера, как предлагалось здесь с использованием комбинации malloc/realloc/free
, но я думаю, что всегда лучше использовать struct
или даже class
в качестве общегошаблон для совместного использования общего контекста между несколькими функциями.
Также обратите внимание, что функцию encrypt
можно вызывать несколько раз (для каждой строки), а encrypt_deinit
будет вызываться только один раз (для каждой инструкции SQL), поэтомуВы должны освободить или повторно использовать предыдущий буфер в encrypt
перед выделением нового.