Files
QTradeProgram/FTAPI/FTAPIImp.cpp
2025-08-15 15:57:31 +08:00

651 lines
17 KiB
C++

#include "FTAPIImp.h"
using namespace std;
CLock FTAPIImp::m_safe;
static set<FTAPIImp*> s_setImp;
static CLock m_safeImp;
static void OnDisConnectCallback(FTAPIChannelPtr pChannel, i64_t nErrCode)
{
CAutoLock(m_safeImp);
Foreach_Iter(iter, s_setImp)
{
FTAPIImp* pImp = *iter;
If_Do(IsNotNullPtr(pImp), pImp->OnDisConnect(pChannel, nErrCode));
}
}
static void OnInitConnectCallback(FTAPIChannelPtr pChannel, i64_t nErrCode, const char* strDesc)
{
CAutoLock(m_safeImp);
Foreach_Iter(iter, s_setImp)
{
FTAPIImp* pImp = *iter;
If_Do(IsNotNullPtr(pImp), pImp->OnInitConnect(pChannel, nErrCode, strDesc));
}
}
static void OnReplyCallback(FTAPIChannelPtr pChannel, FTAPI_ReqReplyType enReqReplyType, const FTAPI_ProtoHeader* pProtoHeader, const i8_t* pProtoData, i32_t nDataLen)
{
CAutoLock(m_safeImp);
Foreach_Iter(iter, s_setImp)
{
FTAPIImp* pImp = *iter;
If_Do(IsNotNullPtr(pImp), pImp->OnReply(pChannel, enReqReplyType, pProtoHeader, pProtoData, nDataLen));
}
}
static void OnPushCallback(FTAPIChannelPtr pChannel, const FTAPI_ProtoHeader* pProtoHeader, const i8_t* pProtoData, i32_t nDataLen)
{
CAutoLock(m_safeImp);
Foreach_Iter(iter, s_setImp)
{
FTAPIImp* pImp = *iter;
If_Do(IsNotNullPtr(pImp), pImp->OnPush(pChannel, pProtoHeader, pProtoData, nDataLen));
}
}
static inline bool PbObj2BinData(const protobuf::Message& pbObj, Buf_t& binData)
{
binData.clear();
i32_t nSize = pbObj.ByteSize();
If_OMWarn_Return(nSize < 0, false);
If_Return(nSize == 0, true); // pb为空
binData.resize(nSize);
If_Do_OMWarn_Return(!pbObj.SerializeToString(&binData), binData.clear(), false);
return true;
}
static inline bool BinData2PbObj(const i8_t* pData, i32_t nDataLen, u8_t nProtoFmtType, protobuf::Message& pbObj)
{
If_OMWarn_Return(IsNullPtr(pData) || nDataLen <= 0, false);
bool bRet = false;
if (nProtoFmtType == FTAPI_ProtoFmtType_Protobuf)
{
bRet = pbObj.ParseFromArray(pData, nDataLen);
}
else if (nProtoFmtType == FTAPI_ProtoFmtType_Json)
{
protobuf::util::JsonParseOptions ops;
ops.ignore_unknown_fields = true;
Str_t strJosn(pData, nDataLen);
protobuf::util::Status status = JsonStringToMessage(strJosn, &pbObj, ops);
bRet = (status.error_code() == protobuf::util::error::OK);
}
If_OMWarn(!bRet);
return bRet;
}
static inline bool IsTrdPorto(u32_t nPorotID)
{
return nPorotID >= FTAPI_ProtoID_Trd_Begin && nPorotID <= FTAPI_ProtoID_Trd_End;
}
static inline bool IsQotPorto(u32_t nPorotID)
{
return nPorotID >= FTAPI_ProtoID_Qot_Begin && nPorotID <= FTAPI_ProtoID_Qot_End;
}
FTAPIImp::FTAPIImp(FTAPI_Conn *pConnApi)
{
m_pFTAPIChannel = CreateFTAPIChannel();
If_OMWarn(IsNullPtr(m_pFTAPIChannel));
{
CAutoLock(m_safeImp);
s_setImp.insert(this);
}
CAutoLock(m_safe);
FTAPIChannel_SetOnDisconnectCallback(m_pFTAPIChannel, OnDisConnectCallback);
FTAPIChannel_SetOnInitConnectCallback(m_pFTAPIChannel, OnInitConnectCallback);
FTAPIChannel_SetOnReplyCallback(m_pFTAPIChannel, OnReplyCallback);
FTAPIChannel_SetOnPushCallback(m_pFTAPIChannel, OnPushCallback);
m_pConnApi = pConnApi;
If_OMWarn(IsNullPtr(m_pConnApi));
}
FTAPIImp::~FTAPIImp(void)
{
{
CAutoLock(m_safeImp);
s_setImp.erase(this);
}
CAutoLock(m_safe);
FTAPIChannel_SetOnDisconnectCallback(m_pFTAPIChannel, nullptr);
FTAPIChannel_SetOnInitConnectCallback(m_pFTAPIChannel, nullptr);
FTAPIChannel_SetOnReplyCallback(m_pFTAPIChannel, nullptr);
FTAPIChannel_SetOnPushCallback(m_pFTAPIChannel, nullptr);
ReleaseFTAPIChannel(m_pFTAPIChannel);
m_pFTAPIChannel = nullptr;
}
void FTAPIImp::SetClientInfo(const char* szClientID, i32_t nClientVer)
{
CAutoLock(m_safe);
FTAPIChannel_SetClientInfo(m_pFTAPIChannel, szClientID, nClientVer);
}
void FTAPIImp::SetProgrammingLanguage(const char* szLanguage)
{
CAutoLock(m_safe);
FTAPIChannel_SetProgrammingLanguage(m_pFTAPIChannel, szLanguage);
}
void FTAPIImp::SetRSAPrivateKey(const char* strRSAPrivateKey)
{
CAutoLock(m_safe);
FTAPIChannel_SetRSAPrivateKey(m_pFTAPIChannel, strRSAPrivateKey);
}
bool FTAPIImp::InitConnect(const char* szIPAddr, u16_t nPort, bool bEnableEncrypt)
{
CAutoLock(m_safe);
return FTAPIChannel_InitConnect(m_pFTAPIChannel, szIPAddr, nPort, bEnableEncrypt);
}
u64_t FTAPIImp::GetConnectID()
{
CAutoLock(m_safe);
return FTAPIChannel_GetConnectID(m_pFTAPIChannel);
}
bool FTAPIImp::Close()
{
CAutoLock(m_safe);
return FTAPIChannel_Close(m_pFTAPIChannel);
}
void FTAPIImp::RegisterConnSpi(FTSPI_Conn *pSpi)
{
CAutoLock(m_safe);
m_pConnSpi = pSpi;
}
void FTAPIImp::UnregisterConnSpi()
{
CAutoLock(m_safe);
m_pConnSpi = nullptr;
}
void FTAPIImp::RegisterQotSpi(FTSPI_Qot *pSpi)
{
CAutoLock(m_safe);
m_pQotSpi = pSpi;
}
void FTAPIImp::UnregisterQotSpi()
{
CAutoLock(m_safe);
m_pQotSpi = nullptr;
}
u32_t FTAPIImp::Sub(const Qot_Sub::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_Sub, stReq);
}
u32_t FTAPIImp::GetGlobalState(const GetGlobalState::Request &stReq)
{
return SendProto(FTAPI_ProtoID_GetGlobalState, stReq);
}
u32_t FTAPIImp::RegQotPush(const Qot_RegQotPush::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_RegQotPush, stReq);
}
u32_t FTAPIImp::GetSubInfo(const Qot_GetSubInfo::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetSubInfo, stReq);
}
u32_t FTAPIImp::GetTicker(const Qot_GetTicker::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetTicker, stReq);
}
u32_t FTAPIImp::GetBasicQot(const Qot_GetBasicQot::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetBasicQot, stReq);
}
u32_t FTAPIImp::GetOrderBook(const Qot_GetOrderBook::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetOrderBook, stReq);
}
u32_t FTAPIImp::GetKL(const Qot_GetKL::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetKL, stReq);
}
u32_t FTAPIImp::GetRT(const Qot_GetRT::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetRT, stReq);
}
u32_t FTAPIImp::GetBroker(const Qot_GetBroker::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetBroker, stReq);
}
u32_t FTAPIImp::RequestRehab(const Qot_RequestRehab::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_RequestRehab, stReq);
}
u32_t FTAPIImp::RequestHistoryKL(const Qot_RequestHistoryKL::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_RequestHistoryKL, stReq);
}
u32_t FTAPIImp::RequestHistoryKLQuota(const Qot_RequestHistoryKLQuota::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_RequestHistoryKLQuota, stReq);
}
u32_t FTAPIImp::GetTradeDate(const Qot_GetTradeDate::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetTradeDate, stReq);
}
u32_t FTAPIImp::GetStaticInfo(const Qot_GetStaticInfo::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetStaticInfo, stReq);
}
u32_t FTAPIImp::GetSecuritySnapshot(const Qot_GetSecuritySnapshot::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetSecuritySnapshot, stReq);
}
u32_t FTAPIImp::GetPlateSet(const Qot_GetPlateSet::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetPlateSet, stReq);
}
u32_t FTAPIImp::GetPlateSecurity(const Qot_GetPlateSecurity::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetPlateSecurity, stReq);
}
u32_t FTAPIImp::GetReference(const Qot_GetReference::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetReference, stReq);
}
u32_t FTAPIImp::GetOwnerPlate(const Qot_GetOwnerPlate::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetOwnerPlate, stReq);
}
u32_t FTAPIImp::GetHoldingChangeList(const Qot_GetHoldingChangeList::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetHoldingChangeList, stReq);
}
u32_t FTAPIImp::GetOptionChain(const Qot_GetOptionChain::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetOptionChain, stReq);
}
u32_t FTAPIImp::GetWarrant(const Qot_GetWarrant::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetWarrant, stReq);
}
u32_t FTAPIImp::GetCapitalFlow(const Qot_GetCapitalFlow::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetCapitalFlow, stReq);
}
u32_t FTAPIImp::GetCapitalDistribution(const Qot_GetCapitalDistribution::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetCapitalDistribution, stReq);
}
u32_t FTAPIImp::GetUserSecurity(const Qot_GetUserSecurity::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetUserSecurity, stReq);
}
u32_t FTAPIImp::ModifyUserSecurity(const Qot_ModifyUserSecurity::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_ModifyUserSecurity, stReq);
}
u32_t FTAPIImp::StockFilter(const Qot_StockFilter::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_StockFilter, stReq);
}
Futu::u32_t FTAPIImp::GetCodeChange(const Qot_GetCodeChange::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetCodeChange, stReq);
}
u32_t FTAPIImp::GetIpoList(const Qot_GetIpoList::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetIpoList, stReq);
}
u32_t FTAPIImp::GetFutureInfo(const Qot_GetFutureInfo::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetFutureInfo, stReq);
}
u32_t FTAPIImp::RequestTradeDate(const Qot_RequestTradeDate::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_RequestTradeDate, stReq);
}
u32_t FTAPIImp::SetPriceReminder(const Qot_SetPriceReminder::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_SetPriceReminder, stReq);
}
u32_t FTAPIImp::GetPriceReminder(const Qot_GetPriceReminder::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetPriceReminder, stReq);
}
u32_t FTAPIImp::GetUserSecurityGroup(const Qot_GetUserSecurityGroup::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetUserSecurityGroup, stReq);
}
u32_t FTAPIImp::GetMarketState(const Qot_GetMarketState::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetMarketState, stReq);
}
u32_t FTAPIImp::GetOptionExpirationDate(const Qot_GetOptionExpirationDate::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Qot_GetOptionExpirationDate, stReq);
}
void FTAPIImp::RegisterTrdSpi(FTSPI_Trd *pSpi)
{
CAutoLock(m_safe);
m_pTrdSpi = pSpi;
}
void FTAPIImp::UnregisterTrdSpi()
{
CAutoLock(m_safe);
m_pTrdSpi = nullptr;
}
bool FTAPIImp::GetPacketID(Common::PacketID &stPacketID)
{
CAutoLock(m_safe);
u64_t nConnectID = GetConnectID();
stPacketID.set_connid(nConnectID);
stPacketID.set_serialno(++m_nTrdSerialNo);
return nConnectID != 0;
}
u32_t FTAPIImp::GetAccList(const Trd_GetAccList::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetAccList, stReq);
}
u32_t FTAPIImp::UnlockTrade(const Trd_UnlockTrade::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_UnlockTrade, stReq);
}
u32_t FTAPIImp::SubAccPush(const Trd_SubAccPush::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_SubAccPush, stReq);
}
u32_t FTAPIImp::GetFunds(const Trd_GetFunds::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetFunds, stReq);
}
u32_t FTAPIImp::GetPositionList(const Trd_GetPositionList::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetPositionList, stReq);
}
u32_t FTAPIImp::GetMaxTrdQtys(const Trd_GetMaxTrdQtys::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetMaxTrdQtys, stReq);
}
u32_t FTAPIImp::GetOrderList(const Trd_GetOrderList::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetOrderList, stReq);
}
u32_t FTAPIImp::PlaceOrder(const Trd_PlaceOrder::Request &stReq)
{
Trd_PlaceOrder::Request stRealReq;
stRealReq.CopyFrom(stReq);
if (stRealReq.has_c2s())
{
Common::PacketID *pPacketID = stRealReq.mutable_c2s()->mutable_packetid();
GetPacketID(*pPacketID);
}
return SendProto(FTAPI_ProtoID_Trd_PlaceOrder, stRealReq);
}
u32_t FTAPIImp::ModifyOrder(const Trd_ModifyOrder::Request &stReq)
{
Trd_ModifyOrder::Request stRealReq;
stRealReq.CopyFrom(stReq);
if (stRealReq.has_c2s())
{
Common::PacketID *pPacketID = stRealReq.mutable_c2s()->mutable_packetid();
GetPacketID(*pPacketID);
}
return SendProto(FTAPI_ProtoID_Trd_ModifyOrder, stRealReq);
}
u32_t FTAPIImp::GetOrderFillList(const Trd_GetOrderFillList::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetOrderFillList, stReq);
}
u32_t FTAPIImp::GetHistoryOrderList(const Trd_GetHistoryOrderList::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetHistoryOrderList, stReq);
}
u32_t FTAPIImp::GetHistoryOrderFillList(const Trd_GetHistoryOrderFillList::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetHistoryOrderFillList, stReq);
}
u32_t FTAPIImp::GetMarginRatio(const Trd_GetMarginRatio::Request &stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetMarginRatio, stReq);
}
u32_t FTAPIImp::GetOrderFee(const Trd_GetOrderFee::Request& stReq)
{
return SendProto(FTAPI_ProtoID_Trd_GetOrderFee, stReq);
}
#define OnReplyNotify(strProtoType, strProtoName) \
case FTAPI_ProtoID_##strProtoType##_##strProtoName:\
{\
strProtoType##_##strProtoName::Response stRsp;\
if (enReqReplyType == FTAPI_ReqReplyType_SvrReply)\
{\
if(!BinData2PbObj(pProtoData, nDataLen, pProtoHeader->nProtoFmtType, stRsp))\
{\
stRsp.set_rettype(Common::RetType_Invalid);\
}\
}\
else {stRsp.set_rettype(enReqReplyType);}\
m_p##strProtoType##Spi->OnReply_##strProtoName(pProtoHeader->nSerialNo, stRsp);\
}\
break;
#define OnTrdReply(strProto) OnReplyNotify(Trd, strProto)
#define OnQotReply(strProto) OnReplyNotify(Qot, strProto)
void FTAPIImp::OnReply(FTAPIChannelPtr pChannel, FTAPI_ReqReplyType enReqReplyType, const FTAPI_ProtoHeader* pProtoHeader, const i8_t* pProtoData, i32_t nDataLen)
{
CAutoLock(m_safe);
If_ReturnVoid(pChannel != m_pFTAPIChannel);
u32_t nProtoID = pProtoHeader->nProtoID;
If_ReturnVoid(IsTrdPorto(nProtoID) && IsNullPtr(m_pTrdSpi));
If_ReturnVoid(IsQotPorto(nProtoID) && IsNullPtr(m_pQotSpi));
switch (nProtoID)
{
case FTAPI_ProtoID_GetGlobalState:
{
if (IsNotNullPtr(m_pQotSpi))
{
GetGlobalState::Response stRsp;
if (enReqReplyType == FTAPI_ReqReplyType_SvrReply)
{
if (!BinData2PbObj(pProtoData, nDataLen, pProtoHeader->nProtoFmtType, stRsp))
{
stRsp.set_rettype(Common::RetType_Invalid);
}
}
else
{
stRsp.set_rettype(enReqReplyType);
}
m_pQotSpi->OnReply_GetGlobalState(pProtoHeader->nSerialNo, stRsp);
}
}
break;
OnQotReply(Sub);
OnQotReply(RegQotPush);
OnQotReply(GetSubInfo);
OnQotReply(GetTicker);
OnQotReply(GetBasicQot);
OnQotReply(GetOrderBook);
OnQotReply(GetKL);
OnQotReply(GetRT);
OnQotReply(GetBroker);
OnQotReply(RequestRehab);
OnQotReply(RequestHistoryKL);
OnQotReply(RequestHistoryKLQuota);
OnQotReply(GetTradeDate);
OnQotReply(GetStaticInfo);
OnQotReply(GetSecuritySnapshot);
OnQotReply(GetPlateSet);
OnQotReply(GetPlateSecurity);
OnQotReply(GetReference);
OnQotReply(GetOwnerPlate);
OnQotReply(GetHoldingChangeList);
OnQotReply(GetOptionChain);
OnQotReply(GetWarrant);
OnQotReply(GetCapitalFlow);
OnQotReply(GetCapitalDistribution);
OnQotReply(GetUserSecurity);
OnQotReply(ModifyUserSecurity);
OnQotReply(StockFilter);
OnQotReply(GetCodeChange);
OnQotReply(GetIpoList);
OnQotReply(GetFutureInfo);
OnQotReply(RequestTradeDate);
OnQotReply(SetPriceReminder);
OnQotReply(GetPriceReminder);
OnQotReply(GetUserSecurityGroup);
OnQotReply(GetMarketState);
OnQotReply(GetOptionExpirationDate);
OnTrdReply(GetAccList);
OnTrdReply(UnlockTrade);
OnTrdReply(SubAccPush);
OnTrdReply(GetFunds);
OnTrdReply(GetPositionList);
OnTrdReply(GetMaxTrdQtys);
OnTrdReply(GetOrderList);
OnTrdReply(PlaceOrder);
OnTrdReply(ModifyOrder);
OnTrdReply(GetOrderFillList);
OnTrdReply(GetHistoryOrderList);
OnTrdReply(GetHistoryOrderFillList);
OnTrdReply(GetMarginRatio);
OnTrdReply(GetOrderFee);
}
}
#define OnPushNotify(strProtoType, strProtoName) \
case FTAPI_ProtoID_##strProtoType##_##strProtoName:\
{\
strProtoType##_##strProtoName::Response stRsp;\
if (!BinData2PbObj(pProtoData, nDataLen, pProtoHeader->nProtoFmtType, stRsp))\
{stRsp.set_rettype(Common::RetType_Invalid);}\
m_p##strProtoType##Spi->OnPush_##strProtoName(stRsp);\
}break;
#define OnTrdPush(strProto) OnPushNotify(Trd, strProto)
#define OnQotPush(strProto) OnPushNotify(Qot, strProto)
void FTAPIImp::OnPush(FTAPIChannelPtr pChannel, const FTAPI_ProtoHeader* pProtoHeader, const i8_t* pProtoData, i32_t nDataLen)
{
CAutoLock(m_safe);
If_ReturnVoid(pChannel != m_pFTAPIChannel);
u32_t nProtoID = pProtoHeader->nProtoID;
If_ReturnVoid(IsTrdPorto(nProtoID) && IsNullPtr(m_pTrdSpi));
If_ReturnVoid(IsQotPorto(nProtoID) && IsNullPtr(m_pQotSpi));
switch (nProtoID)
{
case FTAPI_ProtoID_Notify:
{
if (IsNotNullPtr(m_pQotSpi))
{
Notify::Response stRsp;
if (!BinData2PbObj(pProtoData, nDataLen, pProtoHeader->nProtoFmtType, stRsp))
{
stRsp.set_rettype(Common::RetType_Invalid);
}
m_pQotSpi->OnPush_Notify(stRsp);
}
}
break;
OnQotPush(UpdateTicker);
OnQotPush(UpdateBasicQot);
OnQotPush(UpdateOrderBook);
OnQotPush(UpdateKL);
OnQotPush(UpdateRT);
OnQotPush(UpdateBroker);
OnQotPush(UpdatePriceReminder);
OnTrdPush(UpdateOrder);
OnTrdPush(UpdateOrderFill);
}
}
void FTAPIImp::OnDisConnect(FTAPIChannelPtr pChannel, i64_t nErrCode)
{
CAutoLock(m_safe);
If_ReturnVoid(pChannel != m_pFTAPIChannel);
If_ReturnVoid(IsNullPtr(m_pConnSpi));
m_pConnSpi->OnDisConnect(m_pConnApi, nErrCode);
}
void FTAPIImp::OnInitConnect(FTAPIChannelPtr pChannel, i64_t nErrCode, const char* strDesc)
{
CAutoLock(m_safe);
If_ReturnVoid(pChannel != m_pFTAPIChannel);
If_ReturnVoid(IsNullPtr(m_pConnSpi));
m_pConnSpi->OnInitConnect(m_pConnApi, nErrCode, strDesc);
}
u32_t FTAPIImp::SendProto(u32_t nProtoID, const protobuf::Message& pbObj)
{
CAutoLock(m_safe);
Buf_t binData;
If_OMWarn_Return(!PbObj2BinData(pbObj, binData), 0);
return FTAPIChannel_SendProto(m_pFTAPIChannel, nProtoID, 0, binData.data(), ContainerSize(binData));
}