MyException - 我的异常网
当前位置:我的异常网» VC/MFC » _declspec(dllimport)的作用到底在哪里呢?该怎么处

_declspec(dllimport)的作用到底在哪里呢?该怎么处理(2)

www.MyException.Cn  网友分享于:2013-02-15  浏览:52次

嘿嘿

虽然__declspec(dllimport)有时也可以使 exe 调用 dll 中的函数,但有时会有错误。

编译器会说什么“连接不一致”
------解决方案--------------------
好像俺在dll中导出,其他地方就声明一个原形,然后就getprocaddr了。

------解决方案--------------------
首先得承认,两种写法没有本质的区别,最终的效果是完全一样的。

另外一个问题
如果单从一个方面来说,第二种方法确实有点是“脱裤子放屁式的做法”,不过不知道楼主考虑了没有,如果不这样写,你在写DLL的时候直接写成
__declspec(dllexport) void HelloWorld();
而在你写完之后,要把这个DLL给其他人使用的时候,你再把.h中的__declspec(dllexport)改成__declspec(dllimport)吗?如果发现一次没有写好,你需要修改,那么你再把__declspec(dllimport)改成__declspec(dllexport),然后开始修改你的动态库,你写完了,再交出去的时候,你再把__declspec(dllexport)改成__declspec(dllimport)吗?如果你要改上1000次,你1000次都这样改吗?
那肯定不好,你把时间都花费到这上面,你会说,这活太低级了
------解决方案--------------------
保持程序的接口严谨性,避免歧义
------解决方案--------------------
你知道一般使用DLL的人要一份函数声明列表的么?
动态加载的除外
这个头文件一般是DLL作者来写的
而这个头文件在作者制作DLL内部也会用到
你作为作者的话可不想多写几分一样的代码吧?
这是出于方便考虑的,脱裤子放屁的是自己,是自己没理解其中真谛
------解决方案--------------------
你写dll的时候,使用的是dllexport来导出接口,
而别人使用你的dll的时候,相对的来说,是导入接口,即dllimport

使用宏的好处是,只需要一个定义,既可以在你写dll时使用,给别人头文件时也不需要修改相应的定义。
------解决方案--------------------
看见你们讨论这么多了,我来吭一声吧,虽然确实如楼主所说使用起来无错,但其区别是很容易被忽略的,只需要简单的步骤验证一下即可:

假设你的A(EXE或DLL)需要调用B(DLL)中的某个导出函数:
__declspec(dllexport) void HelloWorld();

按照楼主的写法,不用宏,在项目A中直接包含这个头文件,编译、运行……OK。

打开Dependency Walker(其它合适的工具也可以),打开A(.EXE或.DLL)文件,在左边树中选择根节点,看看右边有什么内容?对了,A文件也有导出符号"HelloWorld",这是你希望看到的?

但如果使用VC默认提供的宏,这个现象不会发生。

------解决方案--------------------
这个东西还确实没有仔细地研究过,一直都是相当然的做法,讨论一下也有好处

不过,如果只从字面上来说,楼主的写法就不好,对于DLL来说,那当然是export,而对于使用者来说,那就是import,如果让使用者还是看到export,即使能够成功,也会产生很大疑问甚至误会的

此外,确实需要搞清楚export和import的内部作用是什么,不过,msdn上好像只是说,dllexport和dllimport是microsoft的特别关键字,其它的并没有多说。

建议楼主在微软的论坛里发贴
------解决方案--------------------
大家讨论很热烈,我也来凑一下热闹吧。

楼主提到的问题并不是脱裤子放屁,当你写一个较大的工程,需要导出很多函数的时候作用就大了

在你的dll接口文件中如下定义
C/C++ code

#ifdef _EXPORTING
#define API_DECLSPEC    __declspec(dllexport)
#else
#define API_DECLSPEC    __declspec(dllimport)
#endif

------解决方案--------------------
关于 __declspec(dllimport)我刚才找了一下,有人写过相关的文章,大意是说,不用这个也链接器也能工作,不过用它更好。原文是说:
不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。 

你参看一下这个:http://blog.csdn.net/Repeaterbin/archive/2009/06/15/4269666.aspx

------解决方案--------------------
很久以前我出现过同样的问题,只是偶然才发现多个DLL都导出了相同的符号,经过仔细检查才发现某个头文件用了楼主的这种写法,这个头文件被多个项目引用了,造成了如此结果。不过我的项目都是DLL,你现在没有在EXE中发现导出的符号,是因为编译器在链接时找不到此符号,已经自动忽略了 __declspec(dllexport) 属性。
------解决方案--------------------
1、变量需要显示地导入。
2、如果不使用 __declspec(dllimport),那么编译生成的代码最终会类似:
call 0xXXXXXXXX
0xXXXXXXXX: jmp dword ptr __imp_function
而如果使用了dllimport,连接器会直接生成如下代码,省去中间的间接调用:
call dword ptr __imp_func
3、在网上看到如果类中用了static变量,也需要使用dllimport。
------解决方案--------------------
用extern就可以用
关键是__declspec(dllexport)更有效
楼下的详解
------解决方案--------------------
探讨

文章评论

Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
我是如何打败拖延症的
我是如何打败拖延症的
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
为什么程序员都是夜猫子
为什么程序员都是夜猫子
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
鲜为人知的编程真相
鲜为人知的编程真相
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
总结2014中国互联网十大段子
总结2014中国互联网十大段子
我的丈夫是个程序员
我的丈夫是个程序员
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
 程序员的样子
程序员的样子
那些争议最大的编程观点
那些争议最大的编程观点
旅行,写作,编程
旅行,写作,编程
代码女神横空出世
代码女神横空出世
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序员都该阅读的书
程序员都该阅读的书
每天工作4小时的程序员
每天工作4小时的程序员
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
一个程序员的时间管理
一个程序员的时间管理
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
如何成为一名黑客
如何成为一名黑客
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
Java程序员必看电影
Java程序员必看电影
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
程序员和编码员之间的区别
程序员和编码员之间的区别
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
程序员必看的十大电影
程序员必看的十大电影
漫画:程序员的工作
漫画:程序员的工作
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
程序员的鄙视链
程序员的鄙视链
10个调试和排错的小建议
10个调试和排错的小建议
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
老程序员的下场
老程序员的下场
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有