c++ dllimport,无法解析的外部符号declspec dllimport
资料来源:http://blog.csdn.net/clever101/
是时候总结一下__declspec(dllimport)的作用了。可能有人会问:_ _ DELSPEC (DLLIMPORT)和_ _ DELSPEC (DLLExport)是一对。在动态链接库中,导出_ _ DELSPEC (DLLExport)和_ _ DELSPEC (DLLIMPORT)。就像一个国家,既有出口,也有进口。有什么难理解的?这是一种自然的思维方式,我一开始是这样理解的。
但是在两年前的一个项目中,我发现不用__declspec(dllimport)似乎也可以。例如,现在我使用共享MFC DLL: DllDlg创建一个新的常规DLL项目。然后我创建两个新文件:DllApi.h和DllApi.cpp DLAPI。h作为接口文件,DllApi.cpp作为实现文件。
然后在DllApi.h中声明一个函数:
这样的外部应用程序或dll可以调用HelloWorld函数。这里特别提醒一下:有网友说要把_ _ declspec(DLLExport)void hello world()放在DllApi.h中;更改为_ _ declspec(dllimport)void hello world();可以提供给外部呼叫。其实这个没必要。我测试过这个。从那时起,我就有了这样一个问题,大概是这样的:
是不是只剩下一个功能:让外部调用方看起来更自然,知道自己的项目中需要导入哪些接口?__declspec(dllimport)一点实际作用都没有?这个问题一直在我脑海里盘旋。直到最近,我在CSDN论坛上发了一个帖子:
__declspec(dllimport)的作用是什么?
按照上面的说法,虽然可以对外使用CBtt类,但是不能使用CBtt类的GetValue函数。一旦使用,外部符号 public: static int CBtt:m_nValue (?m_nValue@CBtt@@2HA).CBtt类的GetValue函数只能与以下声明一起使用:
3.使用隐式dll时,不添加__declspec(dllimport)是完全可以的。使用上没有区别,只是生成的二进制代码稍微损失了一点效率。
a、在没有__declspec(dllimport)的情况下,使用dll中的函数时,编译器无法区分它是普通函数还是从其他dll导入的函数,所以生成的代码如下:
呼叫地址1
地址1:
Jmp实际函数地址
B.当有__declspec(dllimport)时,编译器知道这是一个要从外部dll导入的函数,这样这个项就留在生成的exe的输入表中,这样在exe运行和PE加载程序加载exe时就可以填充输入地址表IAT。生成的代码如下:
调用dword ptr[表中哪一项对应内存地址](注意:现在不需要jmp stub)。这里
感兴趣的朋友可以参考《编译原理》和PE文件格式。
4.使用__declspec(dllimport)体现了语言的对称美,比如虽然!真意味着假,但我们还是需要假这个关键词,它体现了一种对称美。
感谢的英雄们:superdiablo,wltg2001,ccpaishi,jszj,WizardK,hurryboylqs,精忠荣,jameshooo,glacier3d,winnuke,starnight1981,赖亦灵,yang79tao,ForestDB,周志盆,lxlsymbome。
参考资料:
1._ _ declspec (DLLimport)到底有什么用?
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。