外部"C"与类和DLL [英] extern "C" with class and DLL

查看:52
本文介绍了外部"C"与类和DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

向我展示了使用外部"C" 的C ++ 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;
    };
}

C ++程序正在调用DLL.仅供参考,在Windows 7平台上使用Visual Studio 2017.

The DLL is being called by a C++ program. FYI, using Visual Studio 2017 on Windows 7 platform.

问题 *(均与外部"C" class 相关):

Questions *(all related to the extern "C" and class):

  1. 由于 class 不是C语言,因此这等同于 struct ?
  2. 构造函数有效吗?
  3. 虚拟析构函数是否有效(因为C没有 virtual )?
  4. bool 如何处理?
  5. 在类的外部"C" 中如何处理 static ?
  6. 如何在 extern"C" 块内处理 private 数据?
  7. 如何在 extern"C" 块中处理 noexcept ,构造函数?
  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?

Visual Studio 2017编译器不会使用上述代码生成任何错误或警告.

The Visual Studio 2017 compiler is not generating any errors or warnings with the above code.

VS2017代码分析器仅为构造函数生成警告:

The VS2017 code analyzer only generates a warning for the constructor:

C26439 This kind of function may not throw. Declare it 'noexcept' (f.6).

研究:
与该问题有关的StackOverflow问题提到,"extern"C" 具有解决名称重整的作用,但是,它们没有解决 virtual 上面列出的bool`,私人数据等.

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.

此外,许多与DLL相关的答案建议不要使用非POD结构,因为布局可能在编译器(包括相同版本的编译器)之间改变;因此,例如,字符数组优先于 std :: string .

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.

推荐答案

它不会将代码更改为C.它不会导致C ++名称修改失败-因此,您不能重载暴露为 extern的函数例如,该代码块内的C",但是代码仍然是C ++.

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++.

您只能进行无法通过C调用的操作(在 extern"C" 块中).您正在公开一个C API,但是您仍然可以在幕后使用C ++.只是不在您的外部"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.

这也意味着您不能将成员函数(是否为 virtual )导出为 extern"C" ,因为C没有这样的东西.

This also means that you cannot export member functions (virtual or not) as extern "C" because C has no such thing.

这篇关于外部"C"与类和DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆