“而对于DLL,函数储存在一个独立的动态链接库文件中。在创建Windows程序时,链接过程并不把DLL文件链接到程序上。直到程序运行并调用一个DLLs中的函数时,该程序才要求这个函数的地址。此时Windows才在DLL中寻找被调用函数,并把它的地址传送给调用程序。一般情况下,如果一个应用程序使用了动态链接库,Win32系统保证内存中只有DLL的一份复制品,这是通过内存映射实现的。DLL首先被调入Win32系统的全局堆栈,然后映射到调用这个DLL的进程的地址空间。在Win32系统中,每个进程拥有自己的32位线性地址空间。如果一个DLL被多个进程调用,每个进程都会被分配一份该DLL的映像。”既然是被调入Win32系统的全局堆栈,那么我就想知道,dll的代码区、数据区都拷贝到内存中了吗?
如果这个dll处于网络中的一个位置,映射到调用这个DLL的进程的地址空间时,会不会包含dll的详细地址?IP+端口号+路径……欢迎发表意见!
十分感谢阅读!
如果这个dll处于网络中的一个位置,映射到调用这个DLL的进程的地址空间时,会不会包含dll的详细地址?IP+端口号+路径……欢迎发表意见!
十分感谢阅读!
dll里面是啥?一堆函数?
每个进程只能访问自己的虚拟地址空间,通过进程私有的页目、页表来将虚拟地址和物理地址对应。
所以DLL被调入Win32系统的全局堆栈后,引用它的不同进程的页表就可以指向它所在的同一个物理地址。
在执行时,通过切换进程环境,dll 没有变动物理地址,函数指针在不同的进程内却可以表现为不同的虚拟地址。
至于写 dll 专有的数据区,会自动复制一份,然后将页表指向复制后的物理地址。
这应该是代理模式,实现具体功能的 dll 只在服务器上加载,本地加载的 dll 在调用者和服务器直接进行代理,它内部的确有服务器的信息。
只有进程外组件(ActiveX exe),才可以离开主EXE单独在远程主机中存活,他们之前的联系一般采用TCP或管道(管道似呼也是用TCP?135端口?)。
动态链接分为两阶段,即链接过程和装过程。
当应用程序调用动态链接库中的某个函数时,链接程序并不拷贝被调用函数的代码,而只是从引入库中拷贝一些指示信息,指出被调用函数属于哪个动态链接库(.dll文件)。因此,在应用程序的可执行文件中,存放的不是被调用的函数的代码,而是DLL中该函数的内存地址。程序运行后,当需要调用该函数时,进入装入过程,把应用程序与DLL库一起装入内存,由Windows读入DLL中的函数并运行程序。
可以看出,动态链接是在应用程序被装入到内存时进行的。这样,当多个应用程序调用库中的同一个函数时,不会在内存中有该函数的多个拷贝,而是只有一份拷贝,每个应用程序的可执行文件中装入的只是该函数的内存地址,程序运行时再把应用程序代码与被调用函数代码动态链接起来,从而可以节省内存资源。同时,由于DLL与应用程序分开,即使更新DLL,也不用修改已编译好的可执行文件。
----节选自清华大学出版社《Visual basic 6.0 Win32 API 程序设计》(刘炳文 李凤华著)第1章 1.1.2 动态链接库
exe 进程通过映射调用 dll 函数时,系统保证该函数存在与某个物理页面中。
但是,每个进程有2G的虚拟空间(常规设置),物理内存总是不够用的,所以系统会用到磁盘上的交换文件,将某些虚拟内存的页面临时存放在磁盘上。
而对“已加载”的 dll,理想情况当然是一直驻留在物理内存中,但真要腾出物理内存时,并不需要将该页写入交换文件,下次调用时再从磁盘上的 dll 文件中载入就行了。所以系统会将该 dll 文件锁定。
14 楼所讲的 B 关机后 A 就出错,应该就是 A 系统认为该 dll 失去了锁定,再也不能按照上面的调度方式重新从磁盘载入了,所以报错。
前者无需注册所以即使在共享目录只要有权限就能使用,
后者需要注册,本地没注册不能使用,注册了也是使用本地的activex dll
LX 还有要讲的吗?
没有的话结贴了~~~