虽然论坛里已经有些关于__declspec(dllimport)的讨论,可我还是不太明白,还请高手帮一下
如果用__declspec(dllimport)来修饰一个变量
是把这个变量的地址映射到某个DLL中的变量地址吗?
__declspec(dllimport)都不需要标明这个变量来自哪个DLL,一个可执行文件可能加载很多DLL,那系统怎么确定那个变量来自哪个DLL?
最重要的是我读到的代码引用的变量来自ntoskrnl.exe,难道系统会把.exe文件也加载到我的进程空间来?

解决方案 »

  1.   

    要使用DLL的公共数据符号和对象必须要使用__declspec(dllimport)
    __declspec(dllimport) Object obj;
    你可以直接在程序中使用obj访问dll中导出的obj变量。关于来自哪个dll,主要是通过lib链接时来确定。
    dll在加载时系统读取它的导入表,里面就有相应导入符号所在的dll名称。.exe和dll文件的格式都是一样的,系统在处理导入表时遇到没有加载的模块,会对其进行加载。
      

  2.   

    关于来自哪个dll,主要是通过lib链接时来确定。
    你指的是调用系统函数LoadLibrary,在解析该dll时再确定__declspec(dllimport)的变量的位置?
      

  3.   

    PE的输入表中有导入函数所在模块的记录。
    加载dll时由LoadLibrary根据导入表获取相应地址。
      

  4.   

    我的的程序都没有显式调用LoadLibrary函数,怎么还是会链接那些DLL?
    我们的程序在默认情况下到底链接了多少DLL啊?
      

  5.   

    因为你link时链接了dll的导入库lib文件,导入库中包含了dll的导出表等信息,所以程序运行时就会自动加载导入库所对应的dll
    Alt+F7,在link的input一项中可以查看要链接的导入库查看程序默认的dll可以用VC6提供的depends工具,也可以debug时直接在状态输出时查看
      

  6.   

    Windows在加载的时候就会加载需要的导入库并填写输入表。
      

  7.   

    "dll的导入库lib文件"是什么?能详细介绍下吗?(或者给我网址也行)
    那些程序一开始就加载的DLL是由编译器插入了LoadLibrary函数调用来加载的还是由操作系统在加载.exe文件的时候直接加载的(也就是在.exe文件中找不到LoadLibrary的调用)?
      

  8.   

    这东西一Google就一大堆啊http://www.cnblogs.com/chio/archive/2008/08/05/1261296.html这一步是在链接过程中实现的,编译器不会插入任何代码,所以应该是OS实现的
    不过估计OS内部还要调用LoadLibrary之类的函数(这个纯属猜测:-) )
      

  9.   


    程序一开始加载的dll是由操作系统加载的。
      

  10.   

    最后问一个问题:用__declspec(dllimport)修饰的变量是不是只能导入那些在程序开始由操作系统加载的DLL中的变量?
    因为根据各位说的,处理这类变量会涉及到链接器的行为.
      

  11.   

    有了__declspec(dllimport)导入变量,系统会加载对应的dll。