1. 用Record接口,要注意 Packed的区别
2. cdecl和stdcall的区别
3. C++导出的函数建议用C格式stdcall导出,使用Def文件定义名称
4. 用VS写的API dll要注意是否引用了MFC的DLL,否则会使LoadLibrary失败,并GetLastError后返回14001
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//
// 代理信息结构
//
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:成功
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 ;