我正在了解 C++1z 的模块提案。我最大的希望是它将取代dllimport
,dllexport
在 windows 上的使用。使用 c++1z 模块,我可以.dll
在 windows 和.so
linux 上构建,避免使用dllimport/dllexport
? 该模块export
是所有平台和编译器都需要的吗?
3 回答
抱歉不行。
C++ 中的模块提议试图解决头文件中的缺点,这对于涉及头文件的代码尤其成问题。
模板通常完全在标头中实现——但这意味着模板的内容将受制于在包含该标头之前发生的任何预处理器定义。
例如,如果您的模板i
用作标识符,并且#define i 2
在模板的标题之前包含类似内容的标题,则您的代码可能会像这样开始:
for (int i=0; i<10 ; i++)
...但是在预处理器完成后,它看起来像这样:
for (int 2=0; 2<20; 2++)
...这显然根本不会编译。
模块解决了这个问题。模块是独立编译的,而不是在头文件中。由于它是独立编译的,因此模块不受其他头文件的影响,除非其源代码包含这些头文件。
同样,在标头中进行的任何预处理器定义都不会影响导入模块的任何代码。模块中唯一在导入该模块的文件中可见的名称是从模块显式导出的名称。
仍然需要 dllexport,但 dllimport 可能是自动的。至少在VS 2015 Update 1 的 C++ 模块中,他们在一条评论中说:
安德鲁·帕多 [MSFT]
@Matthias:程序员现在只需对要在 DLL 边界导出的符号说 __declspec(dllexport) 。__declspec(dllimport) 在使用模块时由编译器处理。
不幸的是,我没有找到任何更可靠的信息。
可能。
我阅读了提交给标准委员会的 c++20 提案——它们现在在 GitHub 上——并且有一个可以涵盖这一点。它提出了一个新的 [[shared]] c++ 属性来执行此操作,并强制 GCC 和 MSVC 等编译器实现它。不幸的是,它可能错过了进入 c++20 规范的窗口,尽管他们还有时间在最后一刻批准它。
我个人希望他们说“确定”并及时添加。这个属性语法的全部意义——以及这些其他语言变化的一半——据说是为了让我们不再需要在普通代码中使用宏和供应商特定的样板文件。说,就像构建一个DLL。所以如果他们不采纳这个提议,他们最终将不得不采纳类似的东西。