﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-永远的cpp-文章分类-win32&amp;mfc</title><link>http://www.cppblog.com/VinsonEx/category/10743.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 06 Mar 2011 07:13:07 GMT</lastBuildDate><pubDate>Sun, 06 Mar 2011 07:13:07 GMT</pubDate><ttl>60</ttl><item><title>__declspec(dllimport) 到底有什么用？ (转载)</title><link>http://www.cppblog.com/VinsonEx/articles/102156.html</link><dc:creator>VinsonEx</dc:creator><author>VinsonEx</author><pubDate>Sat, 28 Nov 2009 04:46:00 GMT</pubDate><guid>http://www.cppblog.com/VinsonEx/articles/102156.html</guid><wfw:comment>http://www.cppblog.com/VinsonEx/comments/102156.html</wfw:comment><comments>http://www.cppblog.com/VinsonEx/articles/102156.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/VinsonEx/comments/commentRss/102156.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/VinsonEx/services/trackbacks/102156.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;我相信写WIN32程序的人，做过DLL，都会很清楚__declspec(dllexport)的作用，它就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法。当然，如果你的DLL里全是C++的类的话，你无法在DEF里指定导出的函数，只能用__declspec(dllexport)导出类。但是，MSDN文档里面，对于__declspec(dllimport)的说明让人感觉有点奇怪，先来看看MSDN里面是怎么说的：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【不使用 __declspec(dllimport) 也能正确编译代码，但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码，是因为它可以确定函数是否存在于 DLL 中，这使得编译器可以生成跳过间接寻址级别的代码，而这些代码通常会出现在跨 DLL 边界的函数调用中。<span style="COLOR: #ff00ff">但是，必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。】</span> <br></p>
<p>&nbsp;&nbsp;&nbsp;初看起来，这段话前面的意思是，不用它也可以正常使用DLL的导出库，但最后一句话又说，<strong>必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量</strong>这个是什么意思？？</p>
<p>&nbsp;&nbsp;&nbsp;那我就来试验一下，假定，你在DLL里只导出一个简单的类，注意，我假定你已经在项目属性中定义了 SIMPLEDLL_EXPORT<br><br></p>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;SimpleDLLClass.h<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #008000">//<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #000000">#ifdef&nbsp;SIMPLEDLL_EXPORT<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;DLL_EXPORT&nbsp;__declspec(dllexport)</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;DLL_EXPORT</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;DLL_EXPORT&nbsp;SimpleDLLClass<br><img id=Codehighlighter1_153_272_Open_Image onclick="this.style.display='none'; Codehighlighter1_153_272_Open_Text.style.display='none'; Codehighlighter1_153_272_Closed_Image.style.display='inline'; Codehighlighter1_153_272_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_153_272_Closed_Image onclick="this.style.display='none'; Codehighlighter1_153_272_Closed_Text.style.display='none'; Codehighlighter1_153_272_Open_Image.style.display='inline'; Codehighlighter1_153_272_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_153_272_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_153_272_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">SimpleDLLClass();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">SimpleDLLClass();<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"><br><img id=Codehighlighter1_228_246_Open_Image onclick="this.style.display='none'; Codehighlighter1_228_246_Open_Text.style.display='none'; Codehighlighter1_228_246_Closed_Image.style.display='inline'; Codehighlighter1_228_246_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_228_246_Closed_Image onclick="this.style.display='none'; Codehighlighter1_228_246_Closed_Text.style.display='none'; Codehighlighter1_228_246_Open_Image.style.display='inline'; Codehighlighter1_228_246_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif"></span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;getValue()&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_228_246_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_228_246_Open_Text><span style="COLOR: #000000">{&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;m_nValue;}</span></span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;m_nValue;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;SimpleDLLClass.cpp<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #008000">//<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">#include&nbsp;&#8220;SimpleDLLClass.h&#8221;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">SimpleDLLClass::SimpleDLLClass()<br><img id=Codehighlighter1_365_379_Open_Image onclick="this.style.display='none'; Codehighlighter1_365_379_Open_Text.style.display='none'; Codehighlighter1_365_379_Closed_Image.style.display='inline'; Codehighlighter1_365_379_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_365_379_Closed_Image onclick="this.style.display='none'; Codehighlighter1_365_379_Closed_Text.style.display='none'; Codehighlighter1_365_379_Open_Image.style.display='inline'; Codehighlighter1_365_379_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_365_379_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_365_379_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">m_nValue</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">SimpleDLLClass::</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">SimpleDLLClass()<br><img id=Codehighlighter1_416_418_Open_Image onclick="this.style.display='none'; Codehighlighter1_416_418_Open_Text.style.display='none'; Codehighlighter1_416_418_Closed_Image.style.display='inline'; Codehighlighter1_416_418_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_416_418_Closed_Image onclick="this.style.display='none'; Codehighlighter1_416_418_Closed_Text.style.display='none'; Codehighlighter1_416_418_Open_Image.style.display='inline'; Codehighlighter1_416_418_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_416_418_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_416_418_Open_Text><span style="COLOR: #000000">{<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
<br>
<p>然后你再使用这个DLL类，在你的APP中include SimpleDLLClass.h时，你的APP的项目不用定义 SIMPLEDLL_EXPORT 所以，DLL_EXPORT 就不会存在了，这个时候，你在APP中，不会遇到问题。这正好对应MSDN上说的__declspec(dllimport)定义与否都可以正常使用。但我们也没有遇到变量不能正常使用呀。 那好，我们改一下SimpleDLLClass,把它的m_nValue改成static,然后在cpp文件中加一行<br></p>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;SimpleDLLClass::m_nValue</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;</span></div>
<p><br>如果你不知道为什么要加这一行，那就回去看看C++的基础。 改完之后，再去LINK一下，你的APP，看结果如何， 结果是LINK告诉你找不到这个m_nValue。明明已经定义了，为什么又没有了？？ 肯定是因为我把m_nValue定义为static的原因。但如果我一定要使用Singleton的Design Pattern的话，那这个类肯定是要有一个静态成员，每次LINK都没有，那不是完了？ 如果你有Platform SDK，用里面的Depend程序看一下，DLL中又的确是有这个m_nValue导出的呀。<br>再回去看看我引用MSDN的那段话的最后一句。 那我们再改一下SimpleDLLClass.h，把那段改成下面的样子:<br></p>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">#ifdef&nbsp;SIMPLEDLL_EXPORT<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;DLL_EXPORT&nbsp;__declspec(dllexport)</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;DLL_EXPORT&nbsp;__declspec(dllimport)</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">#endif</span></div>
<p><br>再LINK，一切正常。原来dllimport是为了更好的处理类中的静态成员变量的，如果没有静态成员变量，那么这个__declspec(dllimport)无所谓。</p>
<br><br><br>
<img src ="http://www.cppblog.com/VinsonEx/aggbug/102156.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/VinsonEx/" target="_blank">VinsonEx</a> 2009-11-28 12:46 <a href="http://www.cppblog.com/VinsonEx/articles/102156.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>