性能测试工具 loadrunner 回调函数处理问题

rywu · 2018年03月06日 · 最后由 雨夜狂奔 回复于 2018年03月06日 · 2348 次阅读

loadrunner 中回调函数是否可用?

最近在测试 一个 c++ 封装的 dll 时,然后自己使用 c 包了一层,准备使用 lr 进行测试。但是 lr 在处理回调时报错。注册回调函数与我测试代码里面一样的,不清楚为啥会报错。

报错信息

报错位置 TdInit(api);此时会回调 TdRegisterCallback 中的 OnFrontEvent

mdrv.exe caused an EXCEPTION_ACCESS_VIOLATION in module <UNKNOWN> at 0023:000000A0

EAX=000000A0  EBX=03E025D0  ECX=005DF800  EDX=005DF800  ESI=046BFAD0
EDI=046BFBA8  EBP=046BFBA8  ESP=046BFAC0  EIP=000000A0  FLG=00010212
CS=0023   DS=002B  SS=002B  ES=002B   FS=0053  GS=002B

lr 中函数如下:

#include "USTPFtdcUserApiStruct.h"
#include "lrs.h"






void  OnFrontEvent(void* pObject, int type, int Reason) {
    printf("%s","connected!\n");
}
void  OnRspEvent(void* pObject, int type, void* pParam, void* pRspInfo, int nRequestID, int bIsLast) {
    printf("%s","rsp\n");
}
void  OnRtnEvent(void* pObject, int type, void* pParam) {
    printf("%s","rtn\n");
}
void  OnErrRtnEvent(void* pObject, int type, void* pParam, void* pRspInfo) {
    printf("%s","errRtn\n");
}

void  OnPackageEvent(void* pObject, int type, int nTopicID, int nSequenceNo) {
    printf("%s","OnPackageEvent");
}

vuser_init()
{



    void *api;
    char * frontip="tcp://192.168.133.41:43613";
    char * QryFrontIp="tcp://192.168.133.41:43618";
    char *pszReqLogFileName="reqlog";
    char *pszRspLogFileName="rsplog";

    void *pobject;
    //OnErrRtnEvent c1=mOnErrRtnEvent;
    //OnPackageEvent c3=NULL;
    //OnFrontEvent  c2=mOnFrontEvent;
    //OnRspEvent    c4=mOnRspEvent;
    //OnRtnEvent    c5=mOnRtnEvent;
    // 

   struct CUstpFtdcReqUserLoginField userfield;










     strcpy(userfield.BrokerID, "0001");
     strcpy(userfield.UserID, "1000004");
     strcpy(userfield.Password, "111111");
     strcpy(userfield.TradingDay, "20180305");


    lr_load_dll("ftdc2c_femas.dll");

    api=(void* )TdCreateFtdcTraderApi("");
    TdSubscribePrivateTopic(api,1);
    TdSubscribePublicTopic(api,1);
    TdSubscribeUserTopic(api,1);

    TdRegisterFront(api,frontip);
    TdRegisterQryFront(api,QryFrontIp);
    ////


    ///
    TdRegisterCallback(api,OnErrRtnEvent,OnFrontEvent,OnPackageEvent,OnRspEvent,OnRtnEvent,api);

    TdInit(api);
   lr_think_time(10);
   sleep(10);
   TdOpenRequestLog(api,pszReqLogFileName);
   TdOpenResponseLog(api,pszRspLogFileName);




    lr_think_time(30);

    TdReqUserLogin(api,&userfield,1);
    //TdDestroyApi(api);



    return 0;
}



其中报错地方为 TdInit(api),该处会有回调函数调用,回调函数注册 TdRegisterCallback(api,OnErrRtnEvent,OnFrontEvent,OnPackageEvent,OnRspEvent,OnRtnEvent,api);
ftdc2c_femas.dll 头文件

/////////////////////////////////////////////////////////////////////////
//// Ftdc C++ => C Adapter
//// Author :sob: 
//// Generated at 2016/8/27 10:26:20
/////////////////////////////////////////////////////////////////////////

#pragma once

#ifdef WIN32
// Windows
#ifdef FTDC2C_EXPORTS
#define FTDC2C_API extern __declspec(dllexport)
#else
#define FTDC2C_API extern __declspec(dllimport)
#endif
#define MYDECL  __stdcall
#else
// Linux
#define FTDC2C_API extern
#define MYDECL  __attribute__((stdcall))
#endif




#include "USTPFtdcUserApiStruct.h"

#ifdef __cplusplus
extern "C" {
#endif

    typedef void( *CbOnErrRtnEvent)(void *pObject, int type, void *pParam, void *pRspInfo);
    typedef void( *CbOnFrontEvent)(void *pObject, int type, int Reason);
    typedef void( *CbOnRspEvent)(void *pObject, int type, void *pParam, void *pRspInfo, int nRequestID, int bIsLast);
    typedef void( *CbOnRtnEvent)(void *pObject, int type, void *pParam);
    typedef void( *CbOnPackageEvent)(void *pObject, int type, int nTopicID, int nSequenceNo);
    /*  行情部分全部注释掉
    FTDC2C_API void MYDECL MdDestroyApi(void *pApi);
    FTDC2C_API void MYDECL MdRegisterCallback(void *pApi, CbOnFrontEvent c1, CbOnPackageEvent c2, CbOnRspEvent c3, CbOnRtnEvent c4, void *pObject);
    FTDC2C_API void * MYDECL MdCreateApi(const char*pszFlowPath);
    FTDC2C_API const char* MYDECL MdGetVersion(int& nMajorVersion, int nMinorVersion);
    FTDC2C_API void MYDECL MdInit(void *pApi);
    FTDC2C_API const char* MYDECL MdGetTradingDay(void *pApi);
    FTDC2C_API void MYDECL MdRegisterFront(void *pApi, char*pszFrontAddress);
    FTDC2C_API void MYDECL MdRegisterNameServer(void *pApi, char*pszNsAddress);
    FTDC2C_API int MYDECL MdRegisterCertificateFile(void *pApi, const char*pszCertFileName, const char*pszKeyFileName, const char*pszCaFileName, const char*pszKeyFilePassword);
    FTDC2C_API void MYDECL MdSubscribeMarketDataTopic(void *pApi, int nTopicID, USTP_TE_RESUME_TYPE nResumeType);
    FTDC2C_API int MYDECL MdSubMarketData(void *pApi, char*ppInstrumentID[], int nCount);
    FTDC2C_API int MYDECL MdUnSubMarketData(void *pApi, char*ppInstrumentID[], int nCount);
    FTDC2C_API void MYDECL MdSetHeartbeatTimeout(void *pApi, unsigned int timeout);
    FTDC2C_API int MYDECL MdReqUserLogin(void *pApi, CUstpFtdcReqUserLoginField*pReqUserLogin, int nRequestID);
    FTDC2C_API int MYDECL MdReqUserLogout(void *pApi, CUstpFtdcReqUserLogoutField*pReqUserLogout, int nRequestID);
    FTDC2C_API int MYDECL MdReqSubscribeTopic(void *pApi, CUstpFtdcDisseminationField*pDissemination, int nRequestID);
    FTDC2C_API int MYDECL MdReqQryTopic(void *pApi, CUstpFtdcDisseminationField*pDissemination, int nRequestID);
    FTDC2C_API int MYDECL MdReqSubMarketData(void *pApi, CUstpFtdcSpecificInstrumentField*pSpecificInstrument, int nRequestID);
    FTDC2C_API int MYDECL MdReqUnSubMarketData(void *pApi, CUstpFtdcSpecificInstrumentField*pSpecificInstrument, int nRequestID);
    */

    FTDC2C_API void MYDECL TdDestroyApi(void *pApi);
    FTDC2C_API void MYDECL TdRegisterCallback(void *pApi, CbOnErrRtnEvent c1, CbOnFrontEvent c2, CbOnPackageEvent c3, CbOnRspEvent c4, CbOnRtnEvent c5, void *pObject);
    //FTDC2C_API void * MYDECL TdCreateApi(const char*pszFlowPath);

    FTDC2C_API  void * MYDECL TdCreateFtdcTraderApi( const char *pszFlowPath);
    FTDC2C_API  const char * MYDECL TdGetVersion( int nMajorVersion, int& nMinorVersion);
    FTDC2C_API void MYDECL TdRelease(void *pApi);
    FTDC2C_API void MYDECL TdInit(void *pApi);
    FTDC2C_API int MYDECL TdJoin(void *pApi);
    FTDC2C_API const char * MYDECL TdGetTradingDay(void *pApi);
    FTDC2C_API void MYDECL TdRegisterFront(void *pApi, char *pszFrontAddress);
    FTDC2C_API void MYDECL TdRegisterQryFront(void *pApi, char *pszFrontAddress);
    FTDC2C_API void MYDECL TdRegisterNameServer(void *pApi, char *pszNsAddress);
    //FTDC2C_API void MYDECL TdRegisterSpi(void *pApi, CUstpFtdcTraderSpi *pSpi);
    FTDC2C_API int MYDECL TdRegisterCertificateFile(void *pApi, const char *pszCertFileName, const char *pszKeyFileName, const char *pszCaFileName, const char *pszKeyFilePassword);
    FTDC2C_API void MYDECL TdSubscribePrivateTopic(void *pApi, USTP_TE_RESUME_TYPE nResumeType);
    FTDC2C_API void MYDECL TdSubscribePublicTopic(void *pApi, USTP_TE_RESUME_TYPE nResumeType);
    FTDC2C_API void MYDECL TdSubscribeUserTopic(void *pApi, USTP_TE_RESUME_TYPE nResumeType);
    FTDC2C_API void MYDECL TdSubscribeForQuote(void *pApi, USTP_TE_RESUME_TYPE nResumeType);
    FTDC2C_API void MYDECL TdSetHeartbeatTimeout(void *pApi, unsigned int timeout);
    FTDC2C_API int MYDECL TdOpenRequestLog(void *pApi, const char *pszReqLogFileName);
    FTDC2C_API int MYDECL TdOpenResponseLog(void *pApi, const char *pszRspLogFileName);
    FTDC2C_API int MYDECL TdReqUserLogin(void *pApi, CUstpFtdcReqUserLoginField *pReqUserLogin, int nRequestID);
    FTDC2C_API int MYDECL TdReqUserLogout(void *pApi, CUstpFtdcReqUserLogoutField *pReqUserLogout, int nRequestID);
    FTDC2C_API int MYDECL TdReqUserPasswordUpdate(void *pApi, CUstpFtdcUserPasswordUpdateField *pUserPasswordUpdate, int nRequestID);
    FTDC2C_API int MYDECL TdReqSettlementInfoConfirm(void *pApi, CUstpFtdcInputSettlementInfoConfirmField *pInputSettlementInfoConfirm, int nRequestID);
    FTDC2C_API int MYDECL TdReqMsgNotifyConfirm(void *pApi, CUstpFtdcInputMsgNotifyConfirmField *pInputMsgNotifyConfirm, int nRequestID);
    FTDC2C_API int MYDECL TdReqOrderInsert(void *pApi, CUstpFtdcInputOrderField *pInputOrder, int nRequestID);
    FTDC2C_API int MYDECL TdReqOrderAction(void *pApi, CUstpFtdcOrderActionField *pOrderAction, int nRequestID);
    FTDC2C_API int MYDECL TdReqQuoteInsert(void *pApi, CUstpFtdcInputQuoteField *pInputQuote, int nRequestID);
    FTDC2C_API int MYDECL TdReqQuoteAction(void *pApi, CUstpFtdcQuoteActionField *pQuoteAction, int nRequestID);
    FTDC2C_API int MYDECL TdReqForQuote(void *pApi, CUstpFtdcReqForQuoteField *pReqForQuote, int nRequestID);
    FTDC2C_API int MYDECL TdReqMarginCombAction(void *pApi, CUstpFtdcInputMarginCombActionField *pInputMarginCombAction, int nRequestID);
    FTDC2C_API int MYDECL TdReqUserDeposit(void *pApi, CUstpFtdcstpUserDepositField *pstpUserDeposit, int nRequestID);
    FTDC2C_API int MYDECL TdReqTransferMoney(void *pApi, CUstpFtdcstpTransferMoneyField *pstpTransferMoney, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryOrder(void *pApi, CUstpFtdcQryOrderField *pQryOrder, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryTrade(void *pApi, CUstpFtdcQryTradeField *pQryTrade, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryUserInvestor(void *pApi, CUstpFtdcQryUserInvestorField *pQryUserInvestor, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryTradingCode(void *pApi, CUstpFtdcQryTradingCodeField *pQryTradingCode, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryInvestorAccount(void *pApi, CUstpFtdcQryInvestorAccountField *pQryInvestorAccount, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryInstrument(void *pApi, CUstpFtdcQryInstrumentField *pQryInstrument, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryExchange(void *pApi, CUstpFtdcQryExchangeField *pQryExchange, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryInvestorPosition(void *pApi, CUstpFtdcQryInvestorPositionField *pQryInvestorPosition, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryComplianceParam(void *pApi, CUstpFtdcQryComplianceParamField *pQryComplianceParam, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryInvestorFee(void *pApi, CUstpFtdcQryInvestorFeeField *pQryInvestorFee, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryInvestorMargin(void *pApi, CUstpFtdcQryInvestorMarginField *pQryInvestorMargin, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryInvestorCombPosition(void *pApi, CUstpFtdcQryInvestorCombPositionField *pQryInvestorCombPosition, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryInvestorLegPosition(void *pApi, CUstpFtdcQryInvestorLegPositionField *pQryInvestorLegPosition, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryInstrumentGroup(void *pApi, CUstpFtdcQryUstpInstrumentGroupField *pQryUstpInstrumentGroup, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryClientMarginCombType(void *pApi, CUstpFtdcQryClientMarginCombTypeField *pQryClientMarginCombType, int nRequestID);
    FTDC2C_API int MYDECL TdReqExecOrderInsert(void *pApi, CUstpFtdcInputExecOrderField *pInputExecOrder, int nRequestID);
    FTDC2C_API int MYDECL TdReqExecOrderAction(void *pApi, CUstpFtdcInputExecOrderActionField *pInputExecOrderAction, int nRequestID);
    FTDC2C_API int MYDECL TdReqQrySettlementInfoConfirm(void *pApi, CUstpFtdcInputSettlementInfoConfirmField *pInputSettlementInfoConfirm, int nRequestID);
    FTDC2C_API int MYDECL TdReqQrySystemTime(void *pApi, CUstpFtdcReqQrySystemTimeField *pReqQrySystemTime, int nRequestID);
    FTDC2C_API int MYDECL TdReqQuerySettlementInfo(void *pApi, CUstpFtdcSettlementQryReqField *pSettlementQryReq, int nRequestID);
    FTDC2C_API int MYDECL TdReqTradingAccountPasswordUpdate(void *pApi, CUstpFtdcTradingAccountPasswordUpdateReqField *pTradingAccountPasswordUpdateReq, int nRequestID);
    FTDC2C_API int MYDECL TdReqQueryTransferSeria(void *pApi, CUstpFtdcTransferSerialFieldReqField *pTransferSerialFieldReq, int nRequestID);
    FTDC2C_API int MYDECL TdReqQueryAccountregister(void *pApi, CUstpFtdcAccountregisterReqField *pAccountregisterReq, int nRequestID);
    FTDC2C_API int MYDECL TdReqFromBankToFutureByFuture(void *pApi, CUstpFtdcTransferFieldReqField *pTransferFieldReq, int nRequestID);
    FTDC2C_API int MYDECL TdReqFromFutureToBankByFuture(void *pApi, CUstpFtdcTransferFieldReqField *pTransferFieldReq, int nRequestID);
    FTDC2C_API int MYDECL TdReqQueryBankAccountMoneyByFuture(void *pApi, CUstpFtdcAccountFieldReqField *pAccountFieldReq, int nRequestID);
    FTDC2C_API int MYDECL TdReqSignUpAccountByFuture(void *pApi, CUstpFtdcSignUpOrCancleAccountReqFieldField *pSignUpOrCancleAccountReqField, int nRequestID);
    FTDC2C_API int MYDECL TdReqCancleAccountByFuture(void *pApi, CUstpFtdcSignUpOrCancleAccountReqFieldField *pSignUpOrCancleAccountReqField, int nRequestID);
    FTDC2C_API int MYDECL TdReqQuerySignUpOrCancleAccountStatus(void *pApi, CUstpFtdcQuerySignUpOrCancleAccountStatusReqFieldField *pQuerySignUpOrCancleAccountStatusReqField, int nRequestID);
    FTDC2C_API int MYDECL TdReqChangeAccountByFuture(void *pApi, CUstpFtdcChangeAccountReqFieldField *pChangeAccountReqField, int nRequestID);
    FTDC2C_API int MYDECL TdReqOpenSimTradeAccount(void *pApi, CUstpFtdcSimTradeAccountInfoField *pSimTradeAccountInfo, int nRequestID);
    FTDC2C_API int MYDECL TdReqCheckOpenSimTradeAccount(void *pApi, CUstpFtdcSimTradeAccountInfoField *pSimTradeAccountInfo, int nRequestID);
    FTDC2C_API int MYDECL TdReqCFMMCTradingAccountKey(void *pApi, CUstpFtdcCFMMCTradingAccountKeyReqField *pCFMMCTradingAccountKeyReq, int nRequestID);
    FTDC2C_API int MYDECL TdReqQryEnableRtnMoneyPositoinChange(void *pApi, CUstpFtdcEnableRtnMoneyPositoinChangeField *pEnableRtnMoneyPositoinChange, int nRequestID);
    FTDC2C_API int MYDECL TdReqQueryHisOrder(void *pApi, CUstpFtdcQryHisOrderField *pQryHisOrder, int nRequestID);
    FTDC2C_API int MYDECL TdReqQueryHisTrade(void *pApi, CUstpFtdcQryHisTradeField *pQryHisTrade, int nRequestID);
    FTDC2C_API int MYDECL TdReqCurrencyPledge(void *pApi, CUstpFtdcCurrencyPledgeField *pCurrencyPledge, int nRequestID);



#ifdef __cplusplus
}
#endif

c++ 调用 dll 测试代码

//#include "USTPFtdcUserApiStruct.h"
#include <windows.h>
#include <stdio.h>
#include "ftdc2c_femas.h"
#include <string>


void  OnFrontEvent(void* pObject, int type, int Reason) {
    printf("%s","connected!\n");
}
void  OnRspEvent(void* pObject, int type, void* pParam, void* pRspInfo, int nRequestID, int bIsLast) {
    printf("%s","rsp\n");
}
void  OnRtnEvent(void* pObject, int type, void* pParam) {
    printf("%s","rtn\n");
}
void  OnErrRtnEvent(void* pObject, int type, void* pParam, void* pRspInfo) {
    printf("%s","errRtn\n");
}

void  OnPackageEvent(void* pObject, int type, int nTopicID, int nSequenceNo) {
    printf("%s","OnPackageEvent");
}


int  main()
{



    void *api;
    char * frontip = "tcp://192.168.133.41:43613";
    char * QryFrontIp = "tcp://192.168.133.41:43618";
    char *pszReqLogFileName = "reqlog";
    char *pszRspLogFileName = "rsplog";

    void *pobject;
    //OnErrRtnEvent c1=mOnErrRtnEvent;
    //OnPackageEvent c3=NULL;
    //OnFrontEvent  c2=mOnFrontEvent;
    //OnRspEvent    c4=mOnRspEvent;
    //OnRtnEvent    c5=mOnRtnEvent;
    // 

    struct CUstpFtdcReqUserLoginField userfield;



    strcpy_s(userfield.BrokerID, "0001");
    strcpy_s(userfield.UserID, "1000004");
    strcpy_s(userfield.Password, "111111");
    strcpy_s(userfield.TradingDay, "20180305");


    //lr_load_dll("ftdc2c_femas.dll");

    api = (void*)TdCreateFtdcTraderApi("");
    TdSubscribePrivateTopic(api, USTP_TERT_RESUME);
    TdSubscribePublicTopic(api, USTP_TERT_RESUME);
    TdSubscribeUserTopic(api, USTP_TERT_RESUME);

    TdRegisterFront(api, frontip);
    TdRegisterQryFront(api, QryFrontIp);
    TdRegisterCallback(api, OnErrRtnEvent, OnFrontEvent, OnPackageEvent, OnRspEvent, OnRtnEvent, api);

    TdInit(api);
    Sleep(10);

    TdOpenRequestLog(api, pszReqLogFileName);
    TdOpenResponseLog(api, pszRspLogFileName);






    TdReqUserLogin(api, &userfield, 1);

    //TdDestroyApi(api);
    system("pause");


    return 0;
}



使用 c++ 调用 dll,正常响应:

调用成功

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 1 条回复 时间 点赞

按我的经验 LR 是无法处理回调的,不知道理解是否有误,还要其他人帮忙确认下。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册