使用void指针参数调用函数的安全方法

时间:2016-07-12 15:12:26

标签: c++ openssl

我正在调用函数documented,如下所示:

int BIO_write_filename(BIO *b, char *name)

以下内容:

std::string filename{"myfile"};
if (BIO_write_filename(bio, filename.c_str()) <= 0) {
    throw std::runtime_error{"Could not prepare output file.\n"};
}

但是我收到以下错误: cannot convert argument 4 from 'const char *' to 'void *'

我发现我实际上在处理宏:

# define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_WRITE,name)

所以我实际呼唤的是:

long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);

从C ++调用此方法的最佳方法是什么?

到目前为止,我考虑了以下两个选项:

选项1:c式演员:

BIO_write_filename(bio, (void*)filename.c_str())

选项2:C ++类型转换:

const void* filename_ptr_c{(filename.c_str())};
void* filename_ptr{const_cast<void*>(filename_ptr_c)};
BIO_write_filename(bio, filename_ptr)

2 个答案:

答案 0 :(得分:1)

我的建议:

BIO_write_filename(bio, const_cast<char*>(filename.c_str()));

答案 1 :(得分:1)

回答你的问题。使用C ++样式转换。它们被添加到C ++中,因为C ++样式转换为取代C样式转换。您可以在此处详细了解C ++强制转换的理由:https://softwareengineering.stackexchange.com/questions/50442/c-style-casts-or-c-style-casts

作为奖励,我建议你删除宏。正如您所见,宏是C ++中的有毒元素。对您的任何一种选择的巨大改进将是:

if(BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE, data(filename)) <= 0L)

这确实使用了C ++ 17:data所以如果你没有权限,可以随意使用const_cast<char*>并允许转换为{{ 1}}隐式发生。