Thomas Matthews
Thomas Matthews

Reputation: 57729

extern "C" with class and DLL

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):

  1. Since class is not C language, will this be equivalent to a struct?
  2. Are constructors valid?
  3. Are virtual destructors valid (since C doesn't have virtual)?
  4. How is the bool handled?
  5. How is static treated inside the extern "C" for the class?
  6. How is private data handled inside the extern "C" block?
  7. How is 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 ofvirtual,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

Answers (1)

Jesper Juhl
Jesper Juhl

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

Related Questions