hur.cn - 华软网

 热门搜索

MFC的高深问题!!!

  作者:未知    来源:网络    更新时间:2011/9/23
各位大侠我想问下面两个问题,帮忙解答一下,谢谢了。
1.MFC常规DLL为什么不能导出MFC的类?
2.MFC扩展DLL为什么能导出MFC的类,但是MFC扩展DLL一定要用动态链接MFC库而用静态链接MFC库就不行呢?

---华软 网友回答---
常规就是不允许,原因还不知道

2.  扩展dll,  没有所谓的动态链接, 静态链接,


 只有共享mfc dll选项


vc6是这样的


  


引用楼主 xiaofang3100 的回复:
各位大侠我想问下面两个问题,帮忙解答一下,谢谢了。
1.MFC常规DLL为什么不能导出MFC的类?
2.MFC扩展DLL为什么能导出MFC的类,但是MFC扩展DLL一定要用动态链接MFC库而用静态链接MFC库就不行呢?

---华软网友回复---
大神帮忙解答一下, 对于扩展mfc dll来说, 怎样才能 LoadLibrary呢?


不想 隐世加载, 这样太浪费内存了



---华软网友回复---
这两个问题中的为什么,其实就是一种标准,一种规范。没有办法解释。

对于问题2中为什么要动态链接,其实原因就是LIB文件的两种用法,一种是静态库,其中包括了所有的符号和指令;另一种是作为动态库的入口,其中只包括了DLL中的导出符号。

为什么是动态连接,就是因为你已经指定了生成的文件是一个动态库DLL,也就是说,指定了动态这部分数据是动态加载的。

如果想要静态连接,那么你需要将原来的DLL,改成生成库,这样就可以静态连接了,不过这样一来,就不是扩展DLL了。

MFC扩展DLL有这样一个比较讨厌的问题,就是生成扩展DLL所依赖的MFC版本,和目标应用程序使用的MFC版本需要一致,至少大版本号要一至,如VC80,则都是VC80。
---华软网友回复---
大神啊 ,你说的 动态链接 ,静态链接 ,只有 规则mfc  dll才有



我不是楼主, 我是第二楼



我问的是: 扩展mfc  dll  只有共享 mfc dll的方式 , 这种方式创建后有

dll入口函数的!!



比如:我可以 写一个自定义的CMyComboBox类,放在 扩展dll 中



可是带来个麻烦,,,

只能#pragma comment(lib, "xx.lib") 方式加载,也就是说随着整个程序结束, dll才从内存中卸载

(假设这个dll只被一个程序加载)

这样,没有LoadLibarary那样的方式 可以及时从内存中卸载!!


如何做,才能 LoadLibarary??

我知道只有函数可以,类是不可以的,,,, 不知道你有没有方法子?









引用 3 楼 tearywang 的回复:
这两个问题中的为什么,其实就是一种标准,一种规范。没有办法解释。

对于问题2中为什么要动态链接,其实原因就是LIB文件的两种用法,一种是静态库,其中包括了所有的符号和指令;另一种是作为动态库的入口,其中只包括了DLL中的导出符号。

为什么是动态连接,就是因为你已经指定了生成的文件是一个动态库DLL,也就是说,指定了动态这部分数据是动态加载的。

如果想要静态连接,那么你需要将原来……

---华软网友回复---
不用强求要用动态加载吧! 怕机子抗不了吗,不会吧!
---华软网友回复---
引用 4 楼 caddor2011 的回复:
大神啊 ,你说的 动态链接 ,静态链接 ,只有 规则mfc  dll才有



我不是楼主, 我是第二楼



我问的是: 扩展mfc  dll  只有共享 mfc dll的方式 , 这种方式创建后有

dll入口函数的!!



比如:我可以 写一个自定义的CMyComboBox类,放在 扩展dll 中



可是带来个麻烦,,,

只能#pragma……


你通过仔细观观察整个DLL的加载和卸载,你会发现这样的问题,你使用#pragma comment进行的隐式链接和使用LoadLibrary显示链接,卸载的结果都一样。在你的应用程序没有真正卸载之前,被加载的DLL,仍然在内存中,并未真正翻译,尽管你调用了对应的释放函数。

C++虽然是编写期是类,但经过编译后,变成了一堆函数,最初的C++编译器,会自动在每个类的函数中添加一个参数,这个参数就是this指针。

你使用二进制编辑器查看LIB文件,LIB文件是我所说的第二种方法时,你会发现一堆符号,规则似乎于 类名称@@方法名称@参数@参数……
这样讲,你应该能明白吧!
---华软网友回复---
应用程序没有从内存中卸载, 它加载的dll也不会被真正卸载?

我一直以为,对于显示LoadLibrary方式来说,只要FreeLibrary后,(我指的是,该dll 只被这个程序调用)

dll立即从内存卸载,降低内存,    


但是如你所说, LoadLibrary方式也不会真正的被卸载, 卸载的结果都一样 ,就意味着:


开发者来说, 两种方式 无论哪一种,毫无意义了啊


功能都一样 ,而且 LoadLibrary 挺烦的





引用 6 楼 tearywang 的回复:
引用 4 楼 caddor2011 的回复:

大神啊 ,你说的 动态链接 ,静态链接 ,只有 规则mfc  dll才有



我不是楼主, 我是第二楼



我问的是: 扩展mfc  dll  只有共享 mfc dll的方式 , 这种方式创建后有

dll入口函数的!!



比如:我可以 写一个自定义的CMyComboBox类,放在 扩展dll 中


……

---华软网友回复---
up up


---华软网友回复---
对于caddor2011的问题:
1.LoadLibrary是运行时加载,也就是你想要你的DLL加载就加载到内存,当不需要的时候你可以调用FreeLibrary释放DLL模块,DLL就从内存中被卸载,所以这种方式我们叫做动态加载,减少了内存开销,减小了应用程序启动时的时间,因为应用程序启动时候要加载DLL到内存。
2.使用#pragma(lib, "*.lib")方式加载DLL也就是隐士加载,应用程序在启动的时候发现了这语句后会把相应的DLL加载到内存,所以用隐士加载很明显会增加应用程序启动时间。但是对于你像要使用DLL的导出类就必须隐士加载DLL,记住这是个规定就行了。
---华软网友回复---
各位大侠我想问下面两个问题,帮忙解答一下,谢谢了。
1.MFC常规DLL为什么不能导出MFC的类?
2.MFC扩展DLL为什么能导出MFC的类,但是MFC扩展DLL一定要用动态链接MFC库而用静态链接MFC库就不行呢?

我想知道上面这些问题的答案,请各位帮忙解释一下MFC的内部机制来回答这些问题,这个应该是MFC的内部一些实现机制决定的。
---华软网友回复---
up up 非常期待答案。。。。
---华软网友回复---
再说一次, 你做个试验 ,  mfc 扩展 dll

只有共享的选项 ,     常规mfc dll才有 静态和动态选项


另外这两个问题,  据说 深入浅出mfc里面也谈到 mfc dll的知识,不知道那本书有没有介绍 ,

一直没有看过这本书。。


另外一个问题:

我也是照着你的理解,   TearyWang的意思是:隐世和显式一样,只有程序结束后 ,dll才卸载,从内存卸载。。。

我不赞同他的说法, 如果如他所说,那么 两者毫无区别了 。  。。。。 




引用 10 楼 xiaofang3100 的回复:
各位大侠我想问下面两个问题,帮忙解答一下,谢谢了。
1.MFC常规DLL为什么不能导出MFC的类?
2.MFC扩展DLL为什么能导出MFC的类,但是MFC扩展DLL一定要用动态链接MFC库而用静态链接MFC库就不行呢?

我想知道上面这些问题的答案,请各位帮忙解释一下MFC的内部机制来回答这些问题,这个应该是MFC的内部一些实现机制决定的。

---华软网友回复---
我想这两个问题主要是MFC的应用程序对象,MFC的模块,线程状态之间有一些关系影响的。MFC对MFC常规DLL,扩展DLL在DLL入口点函数作了一些工作,但是看MFC内核实现代码也没看出为什么,好郁闷,网上说这方面的也不多,求解,upup.....
---华软网友回复---
 对于dll中的类 导出肯定有办法 显式加载 , 据说是com可以 。。;

com不懂, 只是听一个网友说过 。。。。



---华软网友回复---
引用 12 楼 caddor2011 的回复:
再说一次, 你做个试验 , mfc 扩展 dll

只有共享的选项 , 常规mfc dll才有 静态和动态选项


另外这两个问题, 据说 深入浅出mfc里面也谈到 mfc dll的知识,不知道那本书有没有介绍 ,

一直没有看过这本书。。


另外一个问题:

我也是照着你的理解, TearyWang的意思是:隐世和显式一样,只有程序结束后 ,dll才卸载,从内存卸载。。……



caddor2011说的:mfc 扩展 dll只有共享的选项 , 常规mfc dll才有 静态和动态选项。
这个我知道,你说的这个就是我要问的这两个问题呵呵。
---华软网友回复---
帅哥 ,你知道 为什么对于mfc dll来说,会出现许多奇怪的宏吗?
比如: win32 用_declspec(dllexport) 导出宏 ,可是mfc会定义一些类似的导出宏,

俗话说的好,入乡随俗,来到mfc里面,还是用它的宏。。。。。


不知道用_declspec(dllexport)会有什么问题?


我一直都用这个_declspec(dllexport) 在mfc dll中




引用 13 楼 xiaofang3100 的回复:
我想这两个问题主要是MFC的应用程序对象,MFC的模块,线程状态之间有一些关系影响的。MFC对MFC常规DLL,扩展DLL在DLL入口点函数作了一些工作,但是看MFC内核实现代码也没看出为什么,好郁闷,网上说这方面的也不多,求解,upup.....

---华软网友回复---
引用 14 楼 caddor2011 的回复:
对于dll中的类 导出肯定有办法 显式加载 , 据说是com可以 。。;

com不懂, 只是听一个网友说过 。。。。


com也不可能导出类,com也就是导出 C接口导出函数而已,所以可以动态加载,假如DLL中要导出类你就必须要用#pragma(lib, *.lib)去隐士加载。
---华软网友回复---
引用 16 楼 caddor2011 的回复:
帅哥 ,你知道 为什么对于mfc dll来说,会出现许多奇怪的宏吗?
比如: win32 用_declspec(dllexport) 导出宏 ,可是mfc会定义一些类似的导出宏,

俗话说的好,入乡随俗,来到mfc里面,还是用它的宏。。。。。


不知道用_declspec(dllexport)会有什么问题?


我一直都用这个_declspec(dllexport) 在mfc ……


我想知道WHY而不是HOW。
求解 up up up...
---华软网友回复---
有比较深入了解MFC框架的牛人吗?  求解求解。
---华软网友回复---
那么对于 mfc dll来说, 比如 创建一个对话框资源 在dll中


我目前的方法是: 把dll 中的resource.h的对话框的id值拷贝到 调用程序的resource.h中

感觉挺麻烦的。。。。


不知道你有没有什么良策




引用 17 楼 xiaofang3100 的回复:
引用 14 楼 caddor2011 的回复:
对于dll中的类 导出肯定有办法 显式加载 , 据说是com可以 。。;

com不懂, 只是听一个网友说过 。。。。


com也不可能导出类,com也就是导出 C接口导出函数而已,所以可以动态加载,假如DLL中要导出类你就必须要用#pragma(lib, *.lib)去隐士加载。

---华软网友回复---
引用 20 楼 caddor2011 的回复:
那么对于 mfc dll来说, 比如 创建一个对话框资源 在dll中


我目前的方法是: 把dll 中的resource.h的对话框的id值拷贝到 调用程序的resource.h中

感觉挺麻烦的。。。。


不知道你有没有什么良策





引用 17 楼 xiaofang3100 的回复:

引用 14 楼 caddor2011 的回复:
对于dll中的类 ……


1.可以把对话框的创建封装到一个导出函数,那么DLL的调用者调用导出函数就行了。
2.可以提供一个资源DLL,把所有资源都放到这个DLL里面

这个帖子先不讨论你的问题了啊,你又问题可以在开个帖子。
---华软网友回复---
看看这个链接,或者你能理解为什么。
http://www.vczx.com/tutorial/mfc/mfc9.php
---华软网友回复---
引用 22 楼 tearywang 的回复:
看看这个链接,或者你能理解为什么。
http://www.vczx.com/tutorial/mfc/mfc9.php


晕,这个看过,没看明白。
---华软网友回复---
那就不要去深究。与其头疼地去理解,不如多想想,怎么去设计和实现,能解决问题就行,这些东西,是水到渠成的,多年后,你再回头看这个问题,就是过往云烟。而且在不知不觉中更容易明白。

引用 23 楼 xiaofang3100 的回复:
引用 22 楼 tearywang 的回复:
看看这个链接,或者你能理解为什么。
http://www.vczx.com/tutorial/mfc/mfc9.php


晕,这个看过,没看明白。

---华软网友回复---
  class="deleted_message"> 该回复于2011-10-27 08:06:00被版主删除
---华软网友回复---
对于这两个问题自己回答一下,不知道对不对,欢迎指正。

1.MFC扩展DLL可以导出MFC类,因为扩展DLL的资源句柄被链接到了当前模块状态(pModuleState->m_libraryList)。
MFC扩展DLL可以导出MFC类,但是只能被动态链接到MFC库的程序使用,并且扩展DLL本省也要动态链接到MFC。因为
假如是扩展DLL的使用者静态链接MFC库,那么在查找资源的时候只会查找本模块的资源句柄,不会查找pModuleState->m_libraryList的资源,可以跟踪试一下。
假如是扩展DLL本身静态链接MFC库,那么扩展DLL享有一套私有的模块状态,不能跟使用者共享模块状态,也就链接不到使用者的当前模块状态(pModuleState->m_libraryList)中去了。

2.MFC常规DLL不能导出MFC类,跟踪可以发现找不到对话框资源。
找不到对话框资源的原因是常规DLL有自己的模块状态,资源句柄保存在自己的模块状态中。
---华软网友回复---
这个啊,是不是知其然就Okay 了呢..
---华软网友回复---
引用 26 楼 xiaofang3100 的回复:
对于这两个问题自己回答一下,不知道对不对,欢迎指正。

1.MFC扩展DLL可以导出MFC类,因为扩展DLL的资源句柄被链接到了当前模块状态(pModuleState->m_libraryList)。
MFC扩展DLL可以导出MFC类,但是只能被动态链接到MFC库的程序使用,并且扩展DLL本省也要动态链接到MFC。因为
假如是扩展DLL的使用者静态链接MFC库,那么在查找资源的时候只会查找……


基本上就是这个意思。还有些细节,去运用中体会吧。      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。