C++接口注意

1. 用Record接口,要注意 Packed的区别

2. cdeclstdcall的区别

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:成功
接口引用
type
  TTAQEXPProxy 
= record
    m_
type: Integer;
    m_host: 
array[0..31of char;
    m_port: Integer;
    m_userName: 
array[0..51of char;
    m_password: 
array[0..51of char;
    m_domain: 
array[0..51of char;
  
end;
  PTAQEXPProxy 
= ^TTAQEXPProxy;
  TTAQEXPTASK_NODE 
= record
    m_id: integer;
    m_url: 
array[0..1023of char;
    m_path: 
array[0..255of char;
    m_isReload: Boolean;
    m_fileName: 
array[0..31of char;
    m_comments: 
array[0..1023of 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;
原文地址:https://www.cnblogs.com/enli/p/1812748.html