Reputation: 57729
I was presented with a C++ DLL source code that uses extern "C"
:
extern "C"
{
class Something
{
public:
__declspec(dllexport) Something();
__declspec(dllexport) virtual ~Something();
__declspec(dllexport) bool function_one(const char * some_text);
static __declspec(dllexport) char * get_version();
private:
unsigned int m_data;
};
}
The DLL is being called by a C++ program. FYI, using Visual Studio 2017 on Windows 7 platform.
Questions *(all related to the extern "C"
and class
):
class
is not C language, will this be equivalent to a
struct
?virtual
)?bool
handled?static
treated inside the extern "C"
for the class?private
data handled inside the extern "C"
block?noexcept
handled in an extern "C"
block for the
constructor?The Visual Studio 2017 compiler is not generating any errors or warnings with the above code.
The VS2017 code analyzer only generates a warning for the constructor:
C26439 This kind of function may not throw. Declare it 'noexcept' (f.6).
Research:
The questions on StackOverflow related to this issue mention that the "extern "C"has the effect of resolving name mangling. However, they don't address the issues of
virtual,
bool`, private data, and etc. as I listed above.
Also, many DLLs related answers recommend not using non-POD structures because the layout may change between compilers (including same versions of compilers); so for example, character arrays are preferred over std::string
.
Upvotes: 5
Views: 5365
Reputation: 31459
It doesn't change the code to be C. It causes no C++ name mangling to be done - so you cannot overload functions exposed as extern "C"
inside that block, for example, but the code is still C++.
You are just restricted from doing stuff that would not be callable from C (in the extern "C"
block). You are exposing a C API but you can still use C++ behind the scenes. Just not in your extern "C"
part of the interface.
This also means that you cannot export member functions (virtual
or not) as extern "C"
because C has no such thing.
Upvotes: 2