1. 用Record接口,要注意?Packed的區別
2. cdecl和stdcall的區別
3. C++導出的函數建議用C格式stdcall導出,使用Def文件定義名稱
4. 用VS寫的API dll要注意是否引用了MFC的DLL,否則會使LoadLibrary失敗,并GetLastError后返回14001


////?代理信息結構?//
struct?DOWNLOAD_PROXY_INFO
{
????int????m_type;????????????//代理服務器類型,0:HTTP;?1:SOCKS4;?2:SOCKS4a
????char????m_host[32];????????//代理服務器地址
????int????m_port;????????????//代理服務器端口
????char????m_userName[52];????????//代理服務器驗證用戶名稱
????char????m_password[52];????????//代理服務器驗證用戶密碼
};
////?任務節點結構?//
struct?TASK_NODE
{
????int????m_id;????????????//任務id
????char????m_url[1024];????????//目標URL,不能為空
????char????m_path[256];????????//存儲目錄,不能為空
????bool????m_isReload;????????//是否重新下載,用于斷點續傳
????char????m_fileName[32];????????//另存名稱,可以為空,為空文件名同下載的文件名
????char????m_comments[1024];????//下載注釋,可以為空
????int????m_startMode;????????//開始模式,0手工開始,1立即開始
????int????m_threadCount;????????//下載線程數
????int????m_failedRetryCount;????//失敗重試次數
????int????m_failedRetryInterval;????//失敗重試間隔,毫秒
};
////?回調函數指針?//
typedef?void?(WINAPI?*CALL_BACK)(int?taskID,?TASK_INFO?*pTaskInfo);
////?接口函數?//
/*?
????1.初始化函數
????參數:????maxFlow:流量的最大值,單位K/S。范圍0<maxFlow<1024
????????????pCallback:回調函數,格式見下CallBackFunction
????????????isUseProxy:是否使用代理,false:不使用用;true:使用。默認不使用
????????????pProxyInfo:代理類型結構指針,其結構見DOWNLOAD_PROXY_INFO,默認空
????返回值:????-1:初始化失敗;其他值為使用者的ownerID
????注意事項:????此函數必須首先調用
*/
HDL_EXTERN?int?HDL_EXPORTS?WINAPI?DownLoadInitial(int?maxFlow,?CALL_BACK?pCallback,?bool?isUseProxy?=?false,?DOWNLOAD_PROXY_INFO?*pProxyInfo?=?NULL);
/*?
????2.設置最大流量函數
????參數:????ownerID:使用者ID
????????????maxFlowNum:新設置的最大流量值。范圍0<maxFlow<1024
????返回值:????-1:失敗;1:成功
接口引用
struct?DOWNLOAD_PROXY_INFO
{
????int????m_type;????????????//代理服務器類型,0:HTTP;?1:SOCKS4;?2:SOCKS4a
????char????m_host[32];????????//代理服務器地址
????int????m_port;????????????//代理服務器端口
????char????m_userName[52];????????//代理服務器驗證用戶名稱
????char????m_password[52];????????//代理服務器驗證用戶密碼
};
////?任務節點結構?//
struct?TASK_NODE
{
????int????m_id;????????????//任務id
????char????m_url[1024];????????//目標URL,不能為空
????char????m_path[256];????????//存儲目錄,不能為空
????bool????m_isReload;????????//是否重新下載,用于斷點續傳
????char????m_fileName[32];????????//另存名稱,可以為空,為空文件名同下載的文件名
????char????m_comments[1024];????//下載注釋,可以為空
????int????m_startMode;????????//開始模式,0手工開始,1立即開始
????int????m_threadCount;????????//下載線程數
????int????m_failedRetryCount;????//失敗重試次數
????int????m_failedRetryInterval;????//失敗重試間隔,毫秒
};
////?回調函數指針?//
typedef?void?(WINAPI?*CALL_BACK)(int?taskID,?TASK_INFO?*pTaskInfo);
////?接口函數?//
/*?
????1.初始化函數
????參數:????maxFlow:流量的最大值,單位K/S。范圍0<maxFlow<1024
????????????pCallback:回調函數,格式見下CallBackFunction
????????????isUseProxy:是否使用代理,false:不使用用;true:使用。默認不使用
????????????pProxyInfo:代理類型結構指針,其結構見DOWNLOAD_PROXY_INFO,默認空
????返回值:????-1:初始化失敗;其他值為使用者的ownerID
????注意事項:????此函數必須首先調用
*/
HDL_EXTERN?int?HDL_EXPORTS?WINAPI?DownLoadInitial(int?maxFlow,?CALL_BACK?pCallback,?bool?isUseProxy?=?false,?DOWNLOAD_PROXY_INFO?*pProxyInfo?=?NULL);
/*?
????2.設置最大流量函數
????參數:????ownerID:使用者ID
????????????maxFlowNum:新設置的最大流量值。范圍0<maxFlow<1024
????返回值:????-1:失敗;1:成功


type
??TTAQEXPProxy?=?record
????m_type:?Integer;
????m_host:?array[0..31]?of?char;
????m_port:?Integer;
????m_userName:?array[0..51]?of?char;
????m_password:?array[0..51]?of?char;
????m_domain:?array[0..51]?of?char;
??end;
??PTAQEXPProxy?=?^TTAQEXPProxy;
??TTAQEXPTASK_NODE?=?record
????m_id:?integer;
????m_url:?array[0..1023]?of?char;
????m_path:?array[0..255]?of?char;
????m_isReload:?Boolean;
????m_fileName:?array[0..31]?of?char;
????m_comments:?array[0..1023]?of?char;
????m_startMode:?integer;
????m_threadCount:?integer;
????m_failedRetryCount:?integer;
????m_failedRetryInterval:?integer;
??end;
??PTAQEXPTask_Node?=?^TTAQEXPTASK_NODE;
??TTAQEXPDLLCALLBACK?=?procedure(ID:?integer;?Data:?PTAQEXPTask_INFO);stdcall;
??TDownLoadInitial?=?function(Amaxflow:?integer;?ACallBack:?Pointer;
????POwnerName:?pchar;?AUserProxy:?Bool;?AProxy:?PTAQEXPProxy;?LogLevel:?integer):?Integer;?stdcall;
procedure?DoCallBack(ID:?integer;?Data:?PTAQEXPTask_INFO);stdcall;
begin
??TTAQEXPManager.GetInstance.DoUpdatePercent(ID,Data);
end;
procedure?TTAQEXPDownloader.InitDll;
var
??LInit:?TDownLoadInitial;
??LProxy:?PTAQEXPProxy;
??LMAX:?Integer;
begin
??if?not?FstateFlag?then?Exit;
??new(LProxy);
??fillchar(LProxy^,sizeof(TTAQEXPProxy),0);
??LInit?:=?TDownLoadInitial(
????GetProcAddress(FDllHandle,?PChar('DownLoadInitial')));
??if?Assigned(LInit)?then
??begin
????if?TTAQEXPManager.GetInstance.Config.Loaded?then
??????LMAX?:=?TTAQEXPManager.GetInstance.Config.FlowMax
????else
??????LMax?:=?128;
????if?LMAX?<?1?then?LMAX?:=128;??
????if?CreateConfig.ProxyEnable?then
????begin
??????case?CreateConfig.ProxySocksVersion?of
??????svSocks4:
????????LProxy^.m_type?:=?1;
??????svSocks4A:
????????LProxy^.m_type?:=?2;
??????else
????????LProxy^.m_type?:=?0;
??????end;
??????strpcopy(LProxy^.m_host,?CreateConfig.ProxyHost);
??????LProxy^.m_port?:=?strtointdef(CreateConfig.ProxyPort,80);
??????strpCopy(LProxy^.m_userName,?CreateConfig.AuthUsername);
??????strpCopy(LProxy^.m_password,?CreateConfig.AuthPassword);
??????strpCopy(LProxy^.m_domain,?CreateConfig.AuthDomain);
??????FOwnerId?:=?LInit(LMAX,?@DoCallBack,pchar(ConConfigName),?True,?LProxy,0);
????end
????else
??????FOwnerId?:=?LInit(LMAX,?@DoCallBack,pchar(ConConfigName),?false,?LProxy,0);
????if?FOwnerId?=?-1?then
????begin
??????FstateFlag?:=?False;
??????DoLog('DownLoadInitial失敗');
????end;
??end
??else
??begin
????FstateFlag?:=?False;
????Dolog('沒有函數:DownLoadInitial');
??end;
end;
??TTAQEXPProxy?=?record
????m_type:?Integer;
????m_host:?array[0..31]?of?char;
????m_port:?Integer;
????m_userName:?array[0..51]?of?char;
????m_password:?array[0..51]?of?char;
????m_domain:?array[0..51]?of?char;
??end;
??PTAQEXPProxy?=?^TTAQEXPProxy;
??TTAQEXPTASK_NODE?=?record
????m_id:?integer;
????m_url:?array[0..1023]?of?char;
????m_path:?array[0..255]?of?char;
????m_isReload:?Boolean;
????m_fileName:?array[0..31]?of?char;
????m_comments:?array[0..1023]?of?char;
????m_startMode:?integer;
????m_threadCount:?integer;
????m_failedRetryCount:?integer;
????m_failedRetryInterval:?integer;
??end;
??PTAQEXPTask_Node?=?^TTAQEXPTASK_NODE;
??TTAQEXPDLLCALLBACK?=?procedure(ID:?integer;?Data:?PTAQEXPTask_INFO);stdcall;
??TDownLoadInitial?=?function(Amaxflow:?integer;?ACallBack:?Pointer;
????POwnerName:?pchar;?AUserProxy:?Bool;?AProxy:?PTAQEXPProxy;?LogLevel:?integer):?Integer;?stdcall;
procedure?DoCallBack(ID:?integer;?Data:?PTAQEXPTask_INFO);stdcall;
begin
??TTAQEXPManager.GetInstance.DoUpdatePercent(ID,Data);
end;
procedure?TTAQEXPDownloader.InitDll;
var
??LInit:?TDownLoadInitial;
??LProxy:?PTAQEXPProxy;
??LMAX:?Integer;
begin
??if?not?FstateFlag?then?Exit;
??new(LProxy);
??fillchar(LProxy^,sizeof(TTAQEXPProxy),0);
??LInit?:=?TDownLoadInitial(
????GetProcAddress(FDllHandle,?PChar('DownLoadInitial')));
??if?Assigned(LInit)?then
??begin
????if?TTAQEXPManager.GetInstance.Config.Loaded?then
??????LMAX?:=?TTAQEXPManager.GetInstance.Config.FlowMax
????else
??????LMax?:=?128;
????if?LMAX?<?1?then?LMAX?:=128;??
????if?CreateConfig.ProxyEnable?then
????begin
??????case?CreateConfig.ProxySocksVersion?of
??????svSocks4:
????????LProxy^.m_type?:=?1;
??????svSocks4A:
????????LProxy^.m_type?:=?2;
??????else
????????LProxy^.m_type?:=?0;
??????end;
??????strpcopy(LProxy^.m_host,?CreateConfig.ProxyHost);
??????LProxy^.m_port?:=?strtointdef(CreateConfig.ProxyPort,80);
??????strpCopy(LProxy^.m_userName,?CreateConfig.AuthUsername);
??????strpCopy(LProxy^.m_password,?CreateConfig.AuthPassword);
??????strpCopy(LProxy^.m_domain,?CreateConfig.AuthDomain);
??????FOwnerId?:=?LInit(LMAX,?@DoCallBack,pchar(ConConfigName),?True,?LProxy,0);
????end
????else
??????FOwnerId?:=?LInit(LMAX,?@DoCallBack,pchar(ConConfigName),?false,?LProxy,0);
????if?FOwnerId?=?-1?then
????begin
??????FstateFlag?:=?False;
??????DoLog('DownLoadInitial失敗');
????end;
??end
??else
??begin
????FstateFlag?:=?False;
????Dolog('沒有函數:DownLoadInitial');
??end;
end;
?
?
?