用INDY9开发FTP客户端_09
-- 程序结构图及说明
Roger Yang
程序结构图
图中虚线右侧是封装了各种FTP功能的DLL,左侧是用多线程方式调用DLL的应用程序。
instGetFileDllMain是DLL中窗体的实例,窗体包含TIdFTP控件,它从不显示,只是作为TIdFTP控件的容器使用。
DllInterface负责维护与DLL之间的接口,在它的构造函数中会用loadlibrary方法加载DLL,并获得DLL所有接口函数的函数指针。这样DLL的接口函数就被映射到DllInterface的成员函数上。
GetFileThread是下载任务线程类的实例。
由于在应用程序中无论LoadLibrary同一个DLL多少次,都是将这个DLL装载在相同的内存空间中。
所以,在每个工作线程中加载同一个DLL,无法得到多个相互独立的DLL实例。
变通的方法就是在一个DLL中预先创建10个instGetFileDllMain实例,供多线程调用。
创建10个实例就表示同时支持10个工作线程进行FTP下载操作。
一个instGetFileDllMain实例在其生命周期中会被反复多次使用,每次调用时都会做初始化。调用结束后,instGetFileDllMain实例并不会被立刻释放,而是等待被其它线程使用。
只有当整个DLL实例被释放时,才释放这10个instGetFileDllMain实例。
应用程序启动之初会创建一个全局的DllInterface实例,然后每增加一个下载任务就创建一个GetFileThread线程类的实例。
在线程实例的线程函数中会调用DllInterface全局实例的下载文件方法,这个方法已经和DLL中的下载文件方法绑定在一起。
调用方法时有个关键的参数就是线程编号,线程编号从0~9对应DLL中的10个instGetFileDllMain实例。
这样就能保证每个下载任务线程使用DLL中独立的一个instGetFileDllMain实例,不会互相干扰。