外部"C"与类和DLL [英] extern "C" with class and 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
):
- 由于
class
不是C语言,因此这等同于struct
? - 构造函数有效吗?
- 虚拟析构函数是否有效(因为C没有
virtual
)? -
bool
如何处理? - 在类的
外部"C"
中如何处理static
? - 如何在
extern"C"
块内处理private
数据? - 如何在
extern"C"
块中处理noexcept
,构造函数?
- Since
class
is not C language, will this be equivalent to astruct
? - Are constructors valid?
- Are virtual destructors valid (since C doesn't have
virtual
)? - How is the
bool
handled? - How is
static
treated inside theextern "C"
for the class? - How is
private
data handled inside theextern "C"
block? - How is
noexcept
handled in anextern "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 of
virtual,
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屋!