我只是c ++的初学者,对我而言,这似乎是不必要的代码膨胀。我知道dllimport / export用于共享dll功能,但是使用公共/私有访问器有什么问题?
如果我正在创建一个大的dll库,似乎我必须通过每个函数/类,并确保我导出它。使用托管dll(比如来自c#),我不需要做任何事情。将其导入我的项目,只要该功能是公开的,它就可以访问!
答案 0 :(得分:3)
因为当你创建一个更大的dll(或共享库)时,你可能想要将它组成几个目标文件,但是不想在每个文件中公开所有公共(到链接器)的符号。对象文件。也就是说,当一个符号在一个目标文件中是公共的时,就会出现这种情况,目的只是为了使它可用于同一个库中的另一个目标文件。
请注意,public
和private
访问器与目标文件中的私有符号不完全相同。虽然对象中的私有符号(使用全局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)一个完整的类,这是一种稍微懒惰的方式。