Reputation: 11032
I am calling a function documented as follows:
int BIO_write_filename(BIO *b, char *name)
with the following:
std::string filename{"myfile"};
if (BIO_write_filename(bio, filename.c_str()) <= 0) {
throw std::runtime_error{"Could not prepare output file.\n"};
}
But I get the following error:
cannot convert argument 4 from 'const char *' to 'void *'
I discovered that I'm actually dealing with a macro:
# define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_WRITE,name)
So what I'm actually calling is:
long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
What is the best way to call this from C++?
So far I'm considering the following two options:
Option 1: c-style cast:
BIO_write_filename(bio, (void*)filename.c_str())
Option 2: C++ type cast:
const void* filename_ptr_c{(filename.c_str())};
void* filename_ptr{const_cast<void*>(filename_ptr_c)};
BIO_write_filename(bio, filename_ptr)
Upvotes: 2
Views: 220
Reputation: 38959
In answer to your question. Use C++ style casts. They were added to C++ because C++ style casts to supersede C-Style casts. You can read more about the justification for C++ casts here: https://softwareengineering.stackexchange.com/questions/50442/c-style-casts-or-c-style-casts
As a bonus though, I'd suggest you eliminate the macro. As you have seen macros are a toxic element in C++. A vast improvement over either of your options would be:
if(BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE, data(filename)) <= 0L)
This does use C++17's: data
so if you don't have access to that feel free to just use the const_cast<char*>
and allow the cast to void*
to occur implicitly.
Upvotes: 1
Reputation: 206717
My suggestion:
BIO_write_filename(bio, const_cast<char*>(filename.c_str()));
Upvotes: 1