⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfc dll向导(2).htm

📁 我在网上收集的一些有关vcDLL编程的文章。
💻 HTM
📖 第 1 页 / 共 2 页
字号:
  </td>
 </tr>
</table>

<p class=MsoNormal align=left style='text-align:left;mso-pagination:widow-orphan'><span
lang=EN-US style='font-size:9.0pt;font-family:宋体;mso-bidi-font-family:宋体;
display:none;mso-hide:all;mso-font-kerning:0pt'><o:p>&nbsp;</o:p></span></p>

<div align=center>

<table class=MsoNormalTable border=0 cellspacing=0 cellpadding=0 width="96%"
 style='width:96.0%;mso-cellspacing:0cm;mso-padding-alt:0cm 0cm 0cm 0cm'>
 <tr style='mso-yfti-irow:0;mso-yfti-firstrow:yes;height:3.0pt'>
  <td colspan=3 style='padding:0cm 0cm 0cm 0cm;height:3.0pt'>
  <p class=MsoNormal align=left style='text-align:left;mso-pagination:widow-orphan'><span
  lang=EN-US style='font-size:3.0pt;mso-bidi-font-size:9.0pt;font-family:宋体;
  mso-bidi-font-family:宋体;mso-font-kerning:0pt'><o:p>&nbsp;</o:p></span></p>
  </td>
 </tr>
 <tr style='mso-yfti-irow:1;mso-yfti-lastrow:yes'>
  <td valign=top style='padding:0cm 0cm 0cm 0cm' id=fontzoom>
  <p class=MsoNormal align=left style='text-align:left;line-height:15.0pt;
  mso-pagination:widow-orphan'><span lang=EN-US style='font-size:10.0pt;
  font-family:宋体;mso-bidi-font-family:宋体;mso-font-kerning:0pt'><o:p>&nbsp;</o:p></span></p>
  <p class=MsoNormal align=left style='text-align:left;line-height:15.0pt;
  mso-pagination:widow-orphan'><span style='font-size:10.0pt;font-family:宋体;
  mso-bidi-font-family:宋体;mso-font-kerning:0pt'>  使用<span lang=EN-US>DLL</span>的一个比较严重的问题就是编译器之间的兼容性问题。不同的编译器对<span
  lang=EN-US>c </span>函数在二进制级别的实现方式是不同的。所以对基于<span lang=EN-US>C </span>的<span
  lang=EN-US>DLL</span>,如果编译器不同就有很麻烦的。如果创建的是<span lang=EN-US>MFC</span>扩展<span
  lang=EN-US>DLL</span>,就不会存在问题,因为它只能被动态连接到<span lang=EN-US>MFC</span>的客户应用程序。这里不是本文讨论的重点。<span
  lang=EN-US><br>
  <br>
  </span></span><b><span style='font-size:10.0pt;mso-bidi-font-size:12.0pt;
  font-family:宋体;mso-bidi-font-family:宋体;color:blue;mso-font-kerning:0pt'>一、重新编译问题</span></b><b><span
  lang=EN-US style='font-size:10.0pt;font-family:宋体;mso-bidi-font-family:宋体;
  color:blue;mso-font-kerning:0pt'><br>
  </span></b><span style='font-size:10.0pt;font-family:宋体;mso-bidi-font-family:
  宋体;mso-font-kerning:0pt'>我们先来看一个在实际中可能遇到的问题:<span lang=EN-US><br>
  </span>  比如现在建立好了一个<span lang=EN-US>DLL</span>导出了<span class=SpellE><span
  lang=EN-US>CMyClass</span></span>类,客户也能正常使用这个<span lang=EN-US>DLL</span>,假设<span
  class=SpellE><span lang=EN-US>CMyClass</span></span>对象的大小为<span lang=EN-US>30</span>字节。如果我们需要修改<span
  lang=EN-US>DLL</span>中的<span class=SpellE><span lang=EN-US>CMyClass</span></span>类,让它有相同的函数和成员变量,但是给增加了一个私有的成员变量<span
  class=SpellE><span lang=EN-US>int</span></span>类型,现在<span class=SpellE><span
  lang=EN-US>CMyClass</span></span>对象的大小就是<span lang=EN-US>34</span>字节了。当直接把这个新的<span
  lang=EN-US>DLL</span>给客户使用替换掉原来<span lang=EN-US>30</span>字节大小的<span
  lang=EN-US>DLL</span>,客户应用程序期望的是<span lang=EN-US>30</span>字节大小的对象,而现在却变成了一个<span
  lang=EN-US>34</span>字节大小的对象,糟糕,客户程序出错了。<span lang=EN-US><br>
  </span>  类似的问题,如果不是导出<span class=SpellE><span lang=EN-US>CMyClass</span></span>类,而在导出的函数中使用了<span
  class=SpellE><span lang=EN-US>CMyClass</span></span>,改变对象的大小仍然会有问题的。这个时候修改这个问题的唯一办法就是替换客户程序中的<span
  class=SpellE><span lang=EN-US>CMyClass</span></span>的头文件,全部重新编译整个应用程序,让客户程序使用大小为<span
  lang=EN-US>34</span>字节的对象。<span lang=EN-US><br>
  </span>  这就是一个严重的问题,有的时候如果没有客户程序的源代码,那么我们就不能使用这个新的<span lang=EN-US>DLL</span>了。<span
  lang=EN-US><br>
  <br>
  </span></span><b><span style='font-size:10.0pt;mso-bidi-font-size:12.0pt;
  font-family:宋体;mso-bidi-font-family:宋体;color:blue;mso-font-kerning:0pt'>二、解决方法</span></b><span
  style='font-size:10.0pt;font-family:宋体;mso-bidi-font-family:宋体;mso-font-kerning:
  0pt'> <span lang=EN-US> <br>
  </span>为了能避免重新编译客户程序,这里介绍两个方法:(<span lang=EN-US>1</span>)使用接口类。(<span
  lang=EN-US>2</span>)使用创建和销毁类的静态函数。<span lang=EN-US><br>
  1</span>、使用接口类<span lang=EN-US><br>
  </span>  接口类的也就是创建第二个类,它作为要导出类的接口,所以在导出类改变时,也不需要重新编译客户程序,因为接口<span
  class=GramE>类没有</span>发生变化。<span lang=EN-US><br>
  </span>  假设导出的<span class=SpellE><span lang=EN-US>CMyClass</span></span>类有两个函数<span
  class=SpellE><span lang=EN-US>FunctionA</span></span><span lang=EN-US> <span
  class=SpellE>FunctionB</span></span>。现在创建一个接口类<span class=SpellE><span
  lang=EN-US>CMyInterface</span></span>,下面就是在<span lang=EN-US>DLL</span>中的<span
  class=SpellE><span lang=EN-US>CMyInterface</span></span>类的头文件的代码:<span
  lang=EN-US><br>
  # include &quot;<span class=SpellE>MyClass.h</span>&quot;<br>
  class _<span class=SpellE>declspec</span>(<span class=SpellE>dllexport</span>)
  <span class=SpellE>CMyInterface</span><br>
  {<br>
  </span>  <span lang=EN-US> <span class=SpellE>CMyClass</span> *<span
  class=SpellE>pmyclass</span>;<br>
  </span>  <span lang=EN-US> <span class=SpellE>CMyInterface</span>();<br>
  </span>  <span lang=EN-US> ~<span class=SpellE>CMyInterface</span>();<br>
  public:<br>
  </span>   <span class=SpellE><span lang=EN-US>int</span></span><span
  lang=EN-US> <span class=SpellE>FunctionA</span>(<span class=SpellE>int</span>);<br>
  </span>  <span lang=EN-US> <span class=SpellE>int</span> <span class=SpellE>FunctionB</span>(<span
  class=SpellE>int</span>);<br>
  };<br>
  </span>而在客户程序中的头文件稍不同,不需要<span lang=EN-US>INCLUDE</span>语句,因为客户程序没有它的拷贝。相反,使用一个<span
  class=SpellE><span lang=EN-US>CMyClass</span></span>的向前声明,即使没有头文件也能编译:<span
  lang=EN-US><br>
  class _<span class=SpellE>declspec</span>(<span class=SpellE>dllexport</span>)
  <span class=SpellE>CMyInterface</span><br>
  {<br>
  </span>  <span lang=EN-US> class <span class=SpellE>CMyClass</span>;//</span>向前声明<span
  lang=EN-US><br>
  </span>  <span lang=EN-US> <span class=SpellE>CMyClass</span> *<span
  class=SpellE>pmyclass</span>;<br>
  </span>  <span lang=EN-US> <span class=SpellE>CMyInterface</span>();<br>
  </span>  <span lang=EN-US> ~<span class=SpellE>CMyInterface</span>();<br>
  public:<br>
  </span>  <span lang=EN-US> <span class=SpellE>int</span> <span class=SpellE>FunctionA</span>(<span
  class=SpellE>int</span>);<br>
  </span>  <span lang=EN-US> <span class=SpellE>int</span> <span class=SpellE>FunctionB</span>(<span
  class=SpellE>int</span>);<br>
  };<br>
  </span>在<span lang=EN-US>DLL</span>中的<span class=SpellE><span lang=EN-US>CMyInterface</span></span>的实现如下:<span
  lang=EN-US><br>
  <span class=SpellE>CMyInterface::CMyInterface</span>()<br>
  {<br>
  </span>  <span lang=EN-US> <span class=SpellE>pmyclass</span> = new <span
  class=SpellE>CMyClass</span>();<br>
  }<br>
  <span class=SpellE>CMyInterface::~CMyInterface</span>()<br>
  {<br>
  </span>  <span lang=EN-US> delete <span class=SpellE>pmyclass</span>;<br>
  }<br>
  <span class=SpellE>int</span> <span class=SpellE>CMyInterface::FunctionA</span>()<br>
  {<br>
  </span>  <span lang=EN-US> return <span class=SpellE>pmyclass</span>-&gt;<span
  class=SpellE>FunctionA</span>();<br>
  }<br>
  <span class=SpellE>int</span> <span class=SpellE>CMyInterface::FunctionB</span>()<br>
  {<br>
  </span>  <span lang=EN-US> return <span class=SpellE>pmyclass</span>-&gt;<span
  class=SpellE>FunctionB</span>();</span> <span lang=EN-US> <br>
  }<br>
  .....<br>
  </span>对导出类<span class=SpellE><span lang=EN-US>CMyClass</span></span>的每个成员函数,<span
  class=SpellE><span lang=EN-US>CMyInterface</span></span>类都提供自己的对应的函数。客户程序与<span
  class=SpellE><span lang=EN-US>CMyClass</span></span>没有联系,这样任意改<span
  class=SpellE><span lang=EN-US>CMyClass</span></span>也不会有问题,因为<span
  class=SpellE><span lang=EN-US>CMyInterface</span></span>类的大小没有发生变化。即使为了能访问<span
  class=SpellE><span lang=EN-US>CMyClass</span></span>中的新增变量而给<span
  class=SpellE><span lang=EN-US>CMyInterface</span></span>类加了函数也不会有问题的。<span
  lang=EN-US><br>
  </span>  但是这种方法也存在明显的问题,对导出类的每个函数和成员变量都要对应实现,有的时候这个接口类会很庞大。同时增加了客户程序调用所需要的时间。增加了程序的开销。
  <span lang=EN-US><o:p></o:p></span></span></p>
  <p class=MsoNormal align=left style='mso-margin-top-alt:auto;mso-margin-bottom-alt:
  auto;text-align:left;line-height:15.0pt;mso-pagination:widow-orphan'><span
  lang=EN-US style='font-size:10.0pt;font-family:宋体;mso-bidi-font-family:宋体;
  mso-font-kerning:0pt'>2</span><span style='font-size:10.0pt;font-family:宋体;
  mso-bidi-font-family:宋体;mso-font-kerning:0pt'>、使用静态函数<span lang=EN-US><br>
  </span>  还可以使用静态函数来创建和销毁类对象。创建一个导出类的时候,增加两个静态的公有函数<span class=SpellE><span
  lang=EN-US>CreateMe</span></span><span lang=EN-US>()/<span class=SpellE>DestroyMe</span>()</span>,头文件如下:<span
  lang=EN-US><br>
  class _<span class=SpellE>declspec</span>(<span class=SpellE>dllexport</span>)
  <span class=SpellE>CMyClass</span><br>
  {<br>
  </span>  <span lang=EN-US> <span class=SpellE>CMyClass</span>();<br>
  </span>  <span lang=EN-US> ~<span class=SpellE>CMyClass</span>();<br>
  public:<br>
  </span>  <span lang=EN-US> static <span class=SpellE>CMyClass</span> *<span
  class=SpellE>CreateMe</span>();<br>
  </span>  <span lang=EN-US> static void <span class=SpellE>DestroyMe</span>(<span
  class=SpellE>CMyClass</span> *<span class=SpellE>ptr</span>);<br>
  };<br>
  </span>实现函数就是:<span lang=EN-US><br>
  <span class=SpellE>CMyClass</span> * <span class=SpellE>CMyClass::CMyClass</span>()<br>
  {<br>
  </span>  <span lang=EN-US> return new <span class=SpellE>CMyClass</span>;<br>
  }<br>
  void <span class=SpellE>CMyClass::DestroyMe</span>(<span class=SpellE>CMyClass</span>
  *<span class=SpellE>ptr</span>)<br>
  {<br>
  </span>  <span lang=EN-US> delete <span class=SpellE>ptr</span>;<br>
  }<br>
  </span>然后<span class=GramE>象</span>其他<span class=GramE>类一样</span>导出<span
  class=SpellE><span lang=EN-US>CMyClass</span></span>类,这个时候在客户程序中使用这个类的方法稍有不同了。如若想创建一个<span
  class=SpellE><span lang=EN-US>CMyClass</span></span>对象,就应该是:<span lang=EN-US><br>
  <span class=SpellE>CMyClass</span> x;<br>
  <span class=SpellE>CMyClass</span> *<span class=SpellE>ptr</span> = <span
  class=SpellE>CMyClass::CreateMe</span>();<br>
  </span>在使用完后删除:<span lang=EN-US><br>
  <span class=SpellE>CMyClass::DestroyMe</span>(<span class=SpellE>ptr</span>);<o:p></o:p></span></span></p>
  </td>
  <td style='padding:0cm 0cm 0cm 0cm'>
  <p class=MsoNormal align=left style='text-align:left;mso-pagination:widow-orphan'><span
  lang=EN-US style='font-size:10.0pt;mso-font-kerning:0pt'><o:p>&nbsp;</o:p></span></p>
  </td>
  <td style='padding:0cm 0cm 0cm 0cm'>
  <p class=MsoNormal align=left style='text-align:left;mso-pagination:widow-orphan'><span
  lang=EN-US style='font-size:10.0pt;mso-font-kerning:0pt'><o:p>&nbsp;</o:p></span></p>
  </td>
 </tr>
</table>

</div>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

</div>

</body>

</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -