dllexport / dllimport背后的推理?

时间:2015-08-14 05:43:20

标签: c++

我只是c ++的初学者,对我而言,这似乎是不必要的代码膨胀。我知道dllimport / export用于共享dll功能,但是使用公共/私有访问器有什么问题?

如果我正在创建一个大的dll库,似乎我必须通过每个函数/类,并确保我导出它。使用托管dll(比如来自c#),我不需要做任何事情。将其导入我的项目,只要该功能是公开的,它就可以访问!

3 个答案:

答案 0 :(得分:3)

因为当你创建一个更大的dll(或共享库)时,你可能想要将它组成几个目标文件,但是不想在每个文件中公开所有公共(到链接器)的符号。对象文件。也就是说,当一个符号在一个目标文件中是公共的时,就会出现这种情况,目的只是为了使它可用于同一个库中的另一个目标文件。

请注意,publicprivate访问器与目标文件中的私有符号不完全相同。虽然对象中的私有符号(使用全局static限定符创建的fx)文件意味着该符号在目标文件外部根本不可见,而private访问器仅表示该符号不能显示可以从类外部访问(它仍然可以作为公共文件进入目标文件,因为它可以从另一个翻译单元中的同一个类访问)。

如果要导出目标文件中的所有公共符号,可能有一种机制可以执行此操作,而无需使用明确标记每个符号dllexport - 您必须检查文档,显然在那里&#39 ; s a way在微软中。

关于dllimport的故事,您可以在此处阅读:Why/when is __declspec( dllimport ) not needed?

答案 1 :(得分:0)

这个想法是你的模块可以有一些只需要运行的功能,哪些暴露是没有意义的。例如,如果您正在导出Timer类,并且它取决于您编写的某些全局函数以获取当前时间,则您不需要导出所述函数,因为您的库的用户不需要直接依赖它。 对不好的例子感到抱歉..此外,您不需要导出类,使用接口和工厂功能。

//IBob.h

#define DLLAPI __cdecl
class IBob
{
public:
     void DoSomething( ) = 0;
};

__declspec(/*export / import*/) IBob* DLLAPI BobFactory( );



//----------------------------------
//Bob.h

#include "IBob.h"
class Bob : public IBob
{
public:
     void DoSomething( ) override
     {
     //implementation...
     }
private:
     int var;
     int var2;
};

__declspec(dllexport) IBob* DLLAPI BobFactory( )
{
     return new Bob( );
}

答案 2 :(得分:0)

如上所述,这与C ++无关,只是DLL在每种语言中的工作方式(.NET托管的DLL都不同)。当操作系统加载带有DLL的程序时,它必须将EXE中的所有引用修复为从DLL导出的函数,因此使用的程序越少,程序加载的速度就越快。可能在这个时代它没什么区别,但这可以追溯到早期版本的Windows。

顺便说一句,你可以__declspec(dllexport)一个完整的类,这是一种稍微懒惰的方式。