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

解决方案 »

  1.   

    常规就是不允许,原因还不知道2.  扩展dll,  没有所谓的动态链接, 静态链接,
     只有共享mfc dll选项
    vc6是这样的
      
      

  2.   

    大神帮忙解答一下, 对于扩展mfc dll来说, 怎样才能 LoadLibrary呢?
    不想 隐世加载, 这样太浪费内存了
      

  3.   

    这两个问题中的为什么,其实就是一种标准,一种规范。没有办法解释。对于问题2中为什么要动态链接,其实原因就是LIB文件的两种用法,一种是静态库,其中包括了所有的符号和指令;另一种是作为动态库的入口,其中只包括了DLL中的导出符号。为什么是动态连接,就是因为你已经指定了生成的文件是一个动态库DLL,也就是说,指定了动态这部分数据是动态加载的。如果想要静态连接,那么你需要将原来的DLL,改成生成库,这样就可以静态连接了,不过这样一来,就不是扩展DLL了。MFC扩展DLL有这样一个比较讨厌的问题,就是生成扩展DLL所依赖的MFC版本,和目标应用程序使用的MFC版本需要一致,至少大版本号要一至,如VC80,则都是VC80。
      

  4.   

    大神啊 ,你说的 动态链接 ,静态链接 ,只有 规则mfc  dll才有我不是楼主, 我是第二楼我问的是: 扩展mfc  dll  只有共享 mfc dll的方式 , 这种方式创建后有dll入口函数的!!比如:我可以 写一个自定义的CMyComboBox类,放在 扩展dll 中

    可是带来个麻烦,,,只能#pragma comment(lib, "xx.lib") 方式加载,也就是说随着整个程序结束, dll才从内存中卸载(假设这个dll只被一个程序加载)这样,没有LoadLibarary那样的方式 可以及时从内存中卸载!!
    如何做,才能 LoadLibarary??我知道只有函数可以,类是不可以的,,,, 不知道你有没有方法子?
      

  5.   


    你通过仔细观观察整个DLL的加载和卸载,你会发现这样的问题,你使用#pragma comment进行的隐式链接和使用LoadLibrary显示链接,卸载的结果都一样。在你的应用程序没有真正卸载之前,被加载的DLL,仍然在内存中,并未真正翻译,尽管你调用了对应的释放函数。C++虽然是编写期是类,但经过编译后,变成了一堆函数,最初的C++编译器,会自动在每个类的函数中添加一个参数,这个参数就是this指针。你使用二进制编辑器查看LIB文件,LIB文件是我所说的第二种方法时,你会发现一堆符号,规则似乎于 类名称@@方法名称@参数@参数……
    这样讲,你应该能明白吧!
      

  6.   

    应用程序没有从内存中卸载, 它加载的dll也不会被真正卸载?我一直以为,对于显示LoadLibrary方式来说,只要FreeLibrary后,(我指的是,该dll 只被这个程序调用)dll立即从内存卸载,降低内存,    
    但是如你所说, LoadLibrary方式也不会真正的被卸载, 卸载的结果都一样 ,就意味着:
    对开发者来说, 两种方式 无论哪一种,毫无意义了啊
    功能都一样 ,而且 LoadLibrary 挺烦的
      

  7.   

    对于caddor2011的问题:
    1.LoadLibrary是运行时加载,也就是你想要你的DLL加载就加载到内存,当不需要的时候你可以调用FreeLibrary释放DLL模块,DLL就从内存中被卸载,所以这种方式我们叫做动态加载,减少了内存开销,减小了应用程序启动时的时间,因为应用程序启动时候要加载DLL到内存。
    2.使用#pragma(lib, "*.lib")方式加载DLL也就是隐士加载,应用程序在启动的时候发现了这语句后会把相应的DLL加载到内存,所以用隐士加载很明显会增加应用程序启动时间。但是对于你像要使用DLL的导出类就必须隐士加载DLL,记住这是个规定就行了。
      

  8.   

    各位大侠我想问下面两个问题,帮忙解答一下,谢谢了。
    1.MFC常规DLL为什么不能导出MFC的类?
    2.MFC扩展DLL为什么能导出MFC的类,但是MFC扩展DLL一定要用动态链接MFC库而用静态链接MFC库就不行呢?我想知道上面这些问题的答案,请各位帮忙解释一下MFC的内部机制来回答这些问题,这个应该是MFC的内部一些实现机制决定的。
      

  9.   

    再说一次, 你做个试验 ,  mfc 扩展 dll只有共享的选项 ,     常规mfc dll才有 静态和动态选项
    另外这两个问题,  据说 深入浅出mfc里面也谈到 mfc dll的知识,不知道那本书有没有介绍 ,一直没有看过这本书。。
    另外一个问题:我也是照着你的理解,   TearyWang的意思是:隐世和显式一样,只有程序结束后 ,dll才卸载,从内存卸载我不赞同他的说法, 如果如他所说,那么 两者毫无区别了 。  。 
      

  10.   

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

  11.   

     对于dll中的类 导出肯定有办法 显式加载 , 据说是com可以 。。;com不懂, 只是听一个网友说过 。
      

  12.   

    caddor2011说的:mfc 扩展 dll只有共享的选项 , 常规mfc dll才有 静态和动态选项。
    这个我知道,你说的这个就是我要问的这两个问题呵呵。
      

  13.   

    帅哥 ,你知道 为什么对于mfc dll来说,会出现许多奇怪的宏吗?
    比如: win32 用_declspec(dllexport) 导出宏 ,可是mfc会定义一些类似的导出宏,俗话说的好,入乡随俗,来到mfc里面,还是用它的宏。。
    不知道用_declspec(dllexport)会有什么问题?
    我一直都用这个_declspec(dllexport) 在mfc dll中
      

  14.   


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

  15.   


    我想知道WHY而不是HOW。
    求解 up up up...
      

  16.   

    有比较深入了解MFC框架的牛人吗?  求解求解。
      

  17.   

    那么对于 mfc dll来说, 比如 创建一个对话框资源 在dll中
    我目前的方法是: 把dll 中的resource.h的对话框的id值拷贝到 调用程序的resource.h中感觉挺麻烦的。
    不知道你有没有什么良策
      

  18.   


    1.可以把对话框的创建封装到一个导出函数,那么DLL的调用者调用导出函数就行了。
    2.可以提供一个资源DLL,把所有资源都放到这个DLL里面这个帖子先不讨论你的问题了啊,你又问题可以在开个帖子。
      

  19.   

    看看这个链接,或者你能理解为什么。
    http://www.vczx.com/tutorial/mfc/mfc9.php
      

  20.   

    对于这两个问题自己回答一下,不知道对不对,欢迎指正。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有自己的模块状态,资源句柄保存在自己的模块状态中。
      

  21.   

    这个啊,是不是知其然就Okay 了呢..