1. 用Record接口,要注意 Packed的区别
2. cdecl和stdcall的区别
3. C++导出的函数建议用C格式stdcall导出,使用Def文件定义名称
4. 用VS写的API dll要注意是否引用了MFC的DLL,否则会使LoadLibrary失败,并GetLastError后返回14001
Api头文件
//// 代理信息结构 //
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;