Your question might be an "XY problem" (you ask question 'X' but really you'd do better to ask 'Y' if only you knew it might be a better option). This answer poses an alternative that technically doesn't answer the question that you asked, but it can solve the problem that prompted the question:
Compile your legacy C code as C++ and this isn't even an issue.
If you must keep your C code pure C, then any of the other answers are what you're looking for. But if, like me, you're working on a project that uses legacy C code mixed with new C++ code, then perhaps you should start moving the legacy code away from pure C. Of course if you need to keep the legacy code "pure C" because it's shared with a separate project that's still compiled as strict C then this isn't an option, but let's suppose that's not a requirement. I've done this twice now on two large firmware projects with excellent results.
If you compile your C code as C++, then you can start to take advantage of C++ features even in your legacy "C" code. One way to do that is to find a compiler option to treat C as C++ code; e.g. Visual Studio's /TP option (see this SO post for more info). For GCC, change your makefile to use g++. Or, if there is no such option, rename your .c files with .cpp extensions.
Once you're compiling C code as C++, you may run into other minor problems, but those shouldn't be too difficult to work through, and the long-term benefits will outweigh the initial hassle. See this SO post for more information about that. Perhaps the main issue is that if you use malloc(), you will need to typecast the return value before assigning it to a typed pointer.
Once you're compiling your legacy code as C++, then you can do everything in your legacy code that you can do in your new C++ code, so the issue posed by your original question is no longer an issue at all. You #include <string>
in your C file and then just call myCppStruct.some_string.c_str()
any time you need a raw const char*
pointer (e.g. to call other legacy C functions that take const char*
parameters). No need for a utility function to do it for you.