最近在测试 一个 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
//#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;
}