远程调用内核接口的封装类(RCKObjs)

RCKObjs是一个C++类库,包括Application, Function, Connection, Command, Response和Fields六个核心类。Application管理Function及Response执行,Function定义调用模式,Connection处理登录、请求和响应,Command处理参数,Response执行处理,Fields负责字段打包和拆包。提供头文件(RCKObjs.h)和源代码(RCKObjs.cpp)供使用。" 130784402,11183300,MATLAB实现PSO-BP算法时间序列预测,"['神经网络', '优化算法', '时间序列', 'MATLAB编程', '机器学习']
摘要由CSDN通过智能技术生成

RCK 包含 Application, Function, Connection, Command, Response 和 Fields 六
大类, 其主要功能如下:
    a. Application 类主要负责 Function 的组织和 Response 的分发执行;
    b. Function    类主要负责 Function 的定义及按各模式调用;
    c. Connection  类主要负责登录对端应用, Command 请求执行, Response 应答管理,
       以及发送和接收数据等等;
    d. Command     类主要负责函数参数传入, 以及返回值和返回字段值读取;
    e. Response    类主要负责对端指定 Function 请求的执行处理, 如参数读取、返回
       值编辑及提交;
    f. Fields      类主要负责数据库字段值及定义集的组包和拆包。

 

封装类的头文件(RCKObjs.h)

 

// =======================================
// Unit   : RCKernel objects
// Version: 5.0.0.0 (build 2014.07.07)
// Author : Kyee Ye
// Email  : kyee_ye(at)126.com
// Copyright (C) Kyee workroom
// =======================================

#ifndef _RCKObjs_H_
#define _RCKObjs_H_

#include "KYLib.h"
#include "RCKernel.h"

// 使用 RCKernel 的命名空间
namespace RCKernel
{
   namespace __object__
   {

/* begin namespace */

class TRCAppObj;
class TRCFuncObj;
class TRCConnObj;
class TRCCmdObj;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* 初始化/释放单元 */

// 初始化/释放 RCKObjs 单元(注: 内部有引用计数)
void        InitRCKObjs();
void        FreeRCKObjs(bool AForced = false);

// ID -> 对象
TRCCmdObj*  CmdID2Object(void* ACmdID);   // 命令ID -> 对象
TRCFuncObj* FuncID2Object(void* AFuncID); // 函数ID -> 对象

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* 应用对象(TRCAppObj)的相关函数 */

// 创建/释放应用对象
TRCAppObj*  CreateAppObj(const char* AName, const char* APassword, long* ARetCode = NULL);
void        FreeAppObj(TRCAppObj* AppObj);

// 应用对象引用计数增 1
TRCAppObj*  IncRefAppObj(void* AppID);
bool        IncRefAppObj_(TRCAppObj* AppObj);

// 应用对象引用计数增/减 1(注: AppObj 对象必须存在)
void        IncRefAppObj(TRCAppObj* AppObj);
void        DecRefAppObj(TRCAppObj* AppObj);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* 连接对象(TRCConnObj)的相关函数 */

// 创建/释放连接对象(注: AConnID 必须存在)
TRCConnObj* CreateConnObj(void* AConnID, bool ANeedFree, long* ARetCode = NULL);
void        FreeConnObj(TRCConnObj* AConnObj);

// 连接对象引用计数增 1
TRCConnObj* IncRefConnObj(void* AConnID);
bool        IncRefConnObj_(TRCConnObj* AConnObj);

// 连接对象引用计数增/减 1(注: AConnObj 对象必须存在)
void        IncRefConnObj(TRCConnObj* AConnObj);
void        DecRefConnObj(TRCConnObj* AConnObj);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* 命令对象(TRCCmdObj)的相关函数 */

// 创建/释放命令对象(注: AConnObj 必须存在)
TRCCmdObj*  CreateCmdObj(void* AConnID = NULL);
TRCCmdObj*  CreateCmdObj(TRCConnObj* AConnObj);
void        FreeCmdObj(TRCCmdObj* ACmdObj);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* TRCAppObj - RCK 应用类 */

class TRCAppObj
{
private:
   // 映射列表类型
   typedef TKYMapObjKey<void>    TObjList;

public:
   // 连接登录事件
   typedef void (TObject::*TDoConnLogin)(TRCAppObj* AppObj, void* AConnID, bool& AIsRefused);
   typedef struct
   {
      TDoConnLogin   Method;
      void*          Object;
   } TOnConnLogin;

   // 连接登出事件
   typedef void (TObject::*TDoConnLogout)(TRCAppObj* AppObj, void* AConnID);
   typedef struct
   {
      TDoConnLogout  Method;
      void*          Object;
   } TOnConnLogout;

   // 应答事件
   typedef void (TObject::*TDoRespEvent)(TRCAppObj* AppObj, void* AFuncID, void* AConnID);
   typedef struct
   {
      TDoRespEvent   Method;
      void*          Object;
   } TOnRespEvent;

   // 函数释放事件
   typedef void (TObject::*TDoFuncFree)(TRCAppObj* AppObj, TRCFuncObj* AFuncObj);
   typedef struct
   {
      TDoFuncFree    Method;
      void*          Object;
   } TOnFuncFree;

public:
   TRCAppObj();
   virtual ~TRCAppObj();

   // 属性
   void*          Data() const         { return FData; }
   KYString       Name() const         { return FName; }
   void*          AppID() const        { return FAppID; }
   long           State() const        { return RCKAppGetInt(FAppID, kaaState, NULL); }
   long           FuncCount() const    { return RCKAppGetInt(FAppID, kaaFuncCount, NULL); }
   long           ConnCount() const    { return RCKAppGetInt(FAppID, kaaConnCount, NULL); }
   long           MaxThreads() const   { return RCKAppGetInt(FAppID, kaaMaxThreads, NULL); }
   long           MaxConnCount() const { return RCKAppGetInt(FAppID, kaaMaxConnCount, NULL); }

   // 设置属性
   void           SetData(void* AData) { FData = AData; }
   long           SetName(const KYString& AName);
   long           SetPassword(const char* APassword, long ALength)
                  { return RCKAppSetStr(FAppID, kaaPassword, APassword, ALength); }
   long           SetPassword(const KYString& APassword)
                  { return SetPassword((char*)APassword, APassword.Length()); }
   long           SetMaxThreads(long ACount)
                  { return RCKAppSetInt(FAppID, kaaMaxThreads, ACount); }
   long           SetMaxConnCount(long ACount)
                  { return RCKAppSetInt(FAppID, kaaMaxConnCount, ACount); }

   // 读取应用的连接/函数
   void*          ConnID(long AIndex) const
                  { return RCKAppGetObj(FAppID, kaaBaseConnObj + AIndex, NULL); }
   void*          FuncID(long AIndex) const
                  { return RCKAppGetObj(FAppID, kaaBaseFuncObj + AIndex, NULL); }
   void*          FuncID(const char* AName) const
                  { return RCKAppFuncObj(FAppID, AName); }
   char*          FuncName(long AIndex) const
                  { return RCKAppGetStr(FAppID, kaaBaseFuncName + AIndex, NULL); }

   // 开始/结束函数定义
   long           BeginDefs()          { return RCKAppFuncBegin(FAppID); }
   long           EndDefs()            { return RCKAppFuncEnd(FAppID); }

   // 新建/删除/清除函数定义
   TRCFuncObj*    NewFuncObj(const char* AName, long ARetType,  long  ARetSize,
                                                long ACallMode, void* ACallback);
   bool           DeleteFuncObj(TRCFuncObj* AFuncObj);
   void           ClearFuncObjs();

   // 打开/关闭应用/强制注销应用的连接
   long           Open()               { return RCKAppOpen(FAppID); }
   long           Close()              { return RCKAppClose(FAppID); }
   long           Logout(void* AConnID){ return RCKAppLogout(FAppID, AConnID); }

   // 设置事件
   long           SetOnConnLogin(TDoConnLogin AMethod, void* AObject);
   long           SetOnConnLogout(TDoConnLogout AMethod, void* AObject);
   long           SetOnExecResp(TDoRespEvent AMethod, void* AObject);
   long           SetOnRespCancel(TDoRespEvent AMethod, void* AObject);
   long           SetOnRespConfirm(TDoRespEvent AMethod, void* AObject);

   // 事件
   TOnFuncFree    OnFuncFree;

protected:
   // 当前锁
   void           Lock() const         { FLock->Enter(); }
   void           Unlock() const       { FLock->Leave(); }

   // 对象次数增/减 1
   long           IncObjTimes()        { return InterlockedIncrement(&FObjTimes); }
   long           DecObjTimes()        { return InterlockedDecrement(&FObjTimes); }

private:
   // 执行初始化事件/清除函数列表
   void           DoInitEvent();
   void           DoClearFuncObjs();

   // 执行事件方法
   void           DoConnLogin(void* AConnID, bool& AIsRefused);
   void           DoConnLogout(void* AConnID);
   void           DoExecResp(void* AFuncID, void* AConnID);
   void           DoRespCancel(void* AFuncID, void* AConnID);
   void           DoRespConfirm(void* AFuncID, void* AConnID);

   // 事件方法
   void           DoIDDeletion(void* AFuncID);
   void           DoObjDeletion(TRCFuncObj* AFuncObj);

private:
   void*          FData;               // 自定义数据
   TKYCritSect*   FLock;               // 当前锁
   KYString       FName;               // 应用名
   void*          FAppID;              // 应用 ID
   long           FObjTimes;           // 对象引用次数
   TObjList*      FFuncList;           // 函数列表

   // 事件
   TOnConnLogin   FOnConnLogin;        // 连接登录
   TOnConnLogout  FOnConnLogout;       // 连接登出
   TOnRespEvent   FOnExecResp;         // 执行应答
   TOnRespEvent   FOnRespCancel;       // 应答已取消
   TOnRespEvent   FOnRespConfirm;      // 应答已确认

private:
   // 应用事件的回调函数
   static void __stdcall _RCKOnConnLogin(void* AppID, void* AConnID, bool& AIsRefused);
   static void __stdcall _RCKOnConnLogout(void* AppID, void* AConnID);
   static void __stdcall _RCKOnExecResp(void* AppID, void* AFuncID, void* AConnID);
   static void __stdcall _RCKOnRespCancel(void* AppID, void* AFuncID, void* AConnID);
   static void __stdcall _RCKOnRespConfirm(void* AppID, void* AFuncID, void* AConnID);

private:
   friend class TRCKObjs;
};

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* TRCFuncObj - RCK 函数类 */

class TRCFuncObj
{
public:
   TRCFuncObj();
   virtual ~TRCFuncObj();

   // 属性
   void*          Data() const         { return FData; }
   KYString       Name() const         { return FName; }
   void*          FuncID() const       { return FFuncID; }
   TRCAppObj*     AppObj() const       { return FAppObj; }
   bool           Active() const       { return RCKFuncGetInt(FFuncID, kfaActive, NULL) == 1; }

   long           RetType() const      { return RCKFuncGetInt(FFuncID, kfaRetType, NULL); }
   long           RetSize() const      { return RCKFuncGetInt(FFuncID, kfaRetSize, NULL); }
   long           CallMode() const     { return RCKFuncGetInt(FFuncID, kfaCallMode, NULL); }
   void*          Callback() const     { return RCKFuncGetObj(FFuncID, kfaCallback, NULL); }
   bool           NeedConfirm() const  { return RCKFuncGetInt(FFuncID, kfaNeedConfirm, NULL) == 1; }
   bool           NeedEncrypt() const  { return RCKFuncGetInt(FFuncID, kfaNeedEncrypt, NULL) == 1; }

   // 设置属性
   void           SetData(void* AData) { FData = AData; }
   long           SetNeedConfirm(bool ANeed)
                  { return RCKFuncSetInt(FFuncID, kfaNeedConfirm, ANeed); }
   long           SetNeedEncrypt(bool ANeed)
                  { return RCKFuncSetInt(FFuncID, kfaNeedEncrypt, ANeed); }

   // 读取参数定义
   long           ParamCount() const   { return RCKFuncGetInt(FFuncID, kfaParamCount, NULL); }
   long           ParamIndex(const char* AName) const
                  { return RCKFuncParamIndex(FFuncID, AName); }
   long           ParamIndex(const KYString& AName) const
                  { return RCKFuncParamIndex(FFuncID, (char*)AName); }
   KYString       ParamName(long AIndex) const
                  { return RCKFuncGetStr(FFuncID, kfaBaseParamName + AIndex, NULL); }
   long           ParamType(long AIndex) const
                  { return RCKFuncGetInt(FFuncID, kfaBaseParamType + AIndex, NULL); }
   long           ParamSize(long AIndex) const
                  { return RCKFuncGetInt(FFuncID, kfaBaseParamSize + AIndex, NULL); }
   bool           ParamIsRef(long AIndex) const
                  { return RCKFuncGetInt(FFuncID, kfaBaseParamIsRef + AIndex, NULL) == 1; }

   // 读取返回字段定义
   long           FieldCount() const   { return RCKFuncGetInt(FFuncID, kfaFieldCount, NULL); }
   long           FieldIndex(const char* AName) const
                  { return RCKFuncFieldIndex(FFuncID, AName); }
   long           FieldIndex(const KYString& AName) const
                  { return RCKFuncFieldIndex(FFuncID, (char*)AName); }
   KYString       FieldName(long AIndex) const
                  { return RCKFuncGetStr(FFuncID, kfaBaseFieldName + AIndex, NULL); }
   long           FieldType(long AIndex) const
                  { return RCKFuncGetInt(FFuncID, kfaBaseFieldType + AIndex, NULL); }
   long           FieldSize(long AIndex) const
                  { return RCKFuncGetInt(FFuncID, kfaBaseFieldSize + AIndex, NULL); }

   // 添加参数
   long           AddParam(const char* AName, long AType, long ASize = 0, bool AIsRef = false)
                  { return RCKFuncAddParam(FFuncID, AName, AType, ASize, AIsRef); }
   long           AddParam(const KYString& AName, long AType, long ASize = 0, bool AIsRef = false)
                  { return RCKFuncAddParam(FFuncID, (char*)AName, AType, ASize, AIsRef); }

   // 添加返回字段
   long           AddField(const char* AName, long AType, long ASize = 0)
                  { return RCKFuncAddField(FFuncID, AName, AType, ASize); }
   long           AddField(const KYString& AName, long AType, long ASize = 0)
                  { return RCKFuncAddField(FFuncID, (char*)AName, AType, ASize); }

private:
   void*          FData;               // 自定义数据
   KYString       FName;               // 函数名
   void*          FFuncID;             // 函数 ID
   TRCAppObj*     FAppObj;             // 应用对象

private:
   friend class TRCKObjs;
   friend class TRCAppObj;
};

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* TRCConnObj - RCK 连接类 */

class TRCConnObj
{
public:
   // 连接通知事件
   typedef void (TObject::*TDoNotify)(TRCConnObj* AConnObj);
   typedef struct
   {
      TDoNotify      Method;
      void*          Object;
   } TOnNotify;

   // 连接命令返回事件
   typedef void (TObject::*TDoCmdReturn)(TRCConnObj* AConnObj, void* ACmdID, long AResult);
   typedef struct
   {
      TDoCmdReturn   Method;
      void*          Object;
   } TOnCmdReturn;

   // 接收自定义数据事件
   typedef void (TObject::*TDoRecvData)(TRCConnObj* AConnObj, const void* AData, long ASize);
   typedef struct
   {
      TDoRecvData    Method;
      void*          Object;
   } TOnRecvData;

public:
   TRCConnObj(void* AConnID = NULL, bool ANeedFree = false);
   virtual ~TRCConnObj();

   // 属性
   void*          Data() const         { return FData; }
   void*          ConnID() const       { return FConnID; }
   bool           CanEvent() const     { return FCanEvent; }
   bool           NeedFree() const     { return FNeedFree; }

   KYString       Error() const        { return RCKConnGetStr(FConnID, kcaError, NULL); }
   long           Type() const         { return RCKConnGetInt(FConnID, kcaType, NULL); }
   long           State() const        { return RCKConnGetInt(FConnID, kcaState, NULL); }
   long           Timeout() const      { return RCKConnGetInt(FConnID, kcaTimeout, NULL); }
   void*          SlotObj() const      { return RCKConnGetObj(FConnID, kcaSlotObj, NULL); }
   bool           CanLogin() const     { return RCKConnGetInt(FConnID, kcaCanLogin, NULL) == 1; }
   bool           CanBindApp() const   { return RCKConnGetInt(FConnID, kcaCanBindApp, NULL) == 1; }
   bool           IsSyncLink() const   { return RCKConnGetInt(FConnID, kcaIsSyncLink, NULL) == 1; }
   void*          BindAppObj() const   { return RCKConnGetObj(FConnID, kcaBindAppObj, NULL); }
   long           BindTimeout() const  { return RCKConnGetInt(FConnID, kcaBindTimeout, NULL); }
   long           SlotTimeout() const  { return RCKConnGetInt(FConnID, kcaSlotTimeout, NULL); }
   long           SlotMaxSize() const  { return RCKConnGetInt(FConnID, kcaSlotMaxSize, NULL); }
   long           SendQueueSize() const{ return RCKConnGetInt(FConnID, kcaSendQueueSize, NULL); }

   KYString       AppName() const      { return RCKConnGetStr(FConnID, kcaAppName, NULL); }
   KYString       CurrAddr() const     { return RCKConnGetStr(FConnID, kcaCurrAddr, NULL); }
   long           CurrPort() const     { return RCKConnGetInt(FConnID, kcaCurrPort, NULL); }
   KYString       PeerAddr() const     { return RCKConnGetStr(FConnID, kcaPeerAddr, NULL); }
   long           PeerPort() const     { return RCKConnGetInt(FConnID, kcaPeerPort, NULL); }
   long           LastTick() const     { return RCKConnGetInt(FConnID, kcaLastTick, NULL); }

   long           KeepTimeout() const  { return RCKConnGetInt(FConnID, kcaKeepTimeout, NULL); }
   long           KeepInterval() const { return RCKConnGetInt(FConnID, kcaKeepInterval, NULL); }
   long           KeepRetryTimes()const{ return RCKConnGetInt(FConnID, kcaKeepRetryTimes, NULL); }

   long           FuncCount() const    { return RCKConnGetInt(FConnID, kcaFuncCount, NULL); }
   KYString       FuncName(long AIndex) const
                  { return RCKConnGetStr(FConnID, kcaBaseFuncName + AIndex, NULL); }

   // 设置属性
   void           SetData(void* AData) { FData = AData; }
   long           SetTimeout(long ATimeout)
                  { return RCKConnSetInt(FConnID, kcaTimeout, ATimeout); }
   long           SetCanLogin(bool ACanLogin)
                  { return RCKConnSetInt(FConnID, kcaCanLogin, ACanLogin); }
   long           SetCanBindApp(bool ACanBindApp)
                  { return RCKConnSetInt(FConnID, kcaCanBindApp, ACanBindApp); }
   long           SetBindTimeout(long ATimeout)
                  { return RCKConnSetInt(FConnID, kcaBindTimeout, ATimeout); }
   long           SetIsSyncLink(bool AIsSyncLink)
                  { return RCKConnSetInt(FConnID, kcaIsSyncLink, AIsSyncLink); }
   long           SetSlotTimeout(long ATimeout)
                  { return RCKConnSetInt(FConnID, kcaSlotTimeout, ATimeout); }
   long           SetSlotMaxSize(long AMaxSize)
                  { return RCKConnSetInt(FConnID, kcaSlotMaxSize, AMaxSize); }
   long           SetSendQueueSize(long AQueueSize)
                  { return RCKConnSetInt(FConnID, kcaSendQueueSize, AQueueSize); }

   long           SetAppName(const char* AName, long ALength)
                  { return RCKConnSetStr(FConnID, kcaAppName, AName, ALength); }
   long           SetAppName(const KYString& AName)
                  { return SetAppName((char*)AName, AName.Length()); }

   long           SetAppPass(const char* APassword, long ALength)
                  { return RCKConnSetStr(FConnID, kcaAppPass, APassword, ALength); }
   long           SetAppPass(const KYString& APassword)
                  { return SetAppPass((char*)APassword, APassword.Length()); }

   long           SetCurrAddr(const char* Addr, long ALength)
                  { return RCKConnSetStr(FConnID, kcaCurrAddr, Addr, ALength); }
   long           SetCurrAddr(const KYString& Addr)
                  { return SetCurrAddr((char*)Addr, Addr.Length()); }
   long           SetCurrPort(long APort)
                  { return RCKConnSetInt(FConnID, kcaCurrPort, APort); }

   long           SetPeerAddr(const char* Addr, long ALength)
                  { return RCKConnSetStr(FConnID, kcaPeerAddr, Addr, ALength); }
   long           SetPeerAddr(const KYString& Addr)
                  { return SetPeerAddr((char*)Addr, Addr.Length()); }
   long           SetPeerPort(long APort)
                  { return RCKConnSetInt(FConnID, kcaPeerPort, APort); }

   long           SetKeepTimeout(long ATimeout)
                  { return RCKConnSetInt(FConnID, kcaKeepTimeout, ATimeout); }
   long           SetKeepInterval(long AInterval)
                  { return RCKConnSetInt(FConnID, kcaKeepInterval, AInterval); }
   long           SetKeepRetryTimes(long ARetryTimes)
                  { return RCKConnSetInt(FConnID, kcaKeepRetryTimes, ARetryTimes); }

   // slot 扩展属性
   bool           SlotExtBool(long AExt) const
                  { return RCKConnGetInt(FConnID, kcaBaseSlotExt + AExt, NULL) == 1; }
   long           SlotExtInt(long AExt) const
                  { return RCKConnGetInt(FConnID, kcaBaseSlotExt + AExt, NULL); }
   void*          SlotExtObj(long AExt) const
                  { return RCKConnGetObj(FConnID, kcaBaseSlotExt + AExt, NULL); }
   char*          SlotExtStr(long AExt, long* ARetSize = NULL) const
                  { return RCKConnGetStr(FConnID, kcaBaseSlotExt + AExt, ARetSize); }

   // 设置 slot 扩展属性
   long           SetSlotExtInt(long AExt, long AValue)
                  { return RCKConnSetInt(FConnID, kcaBaseSlotExt + AExt, AValue); }
   long           SetSlotExtObj(long AExt, void* AValue)
                  { return RCKConnSetObj(FConnID, kcaBaseSlotExt + AExt, AValue); }
   long           SetSlotExtStr(long AExt, const char* AValue, long ASize)
                  { return RCKConnSetStr(FConnID, kcaBaseSlotExt + AExt, AValue, ASize); }

   // 打开/关闭连接
   long           Open()               { return RCKConnOpen(FConnID); }
   long           Close()              { return RCKConnClose(FConnID); }

   // 登录/登出对端应用
   long           Login()              { return RCKConnLogin(FConnID); }
   long           Logout()             { return RCKConnLogout(FConnID); }

   // 加载对端应用的函数列表
   long           LoadDefs()           { return RCKConnLoad(FConnID); }

   // 发送数据(参数 ANeedPack 表示数据是否需要压缩发送)
   long           SendData(const void* AData, long ASize, bool ANeedPack)
                  { return RCKConnSendData(FConnID, AData, ASize, ANeedPack); }

   // 设置事件
   long           SetOnConnect(TDoNotify AMethod, void* AObject);
   long           SetOnDisconnect(TDoNotify AMethod, void* AOb
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值