dll里面有个函数是这样写的 registerErrorMessage(PFNERRORCALLBACK pfnErrorMessage); 其中PFNERRORCALLBACK 的定义是 typedef void (*PFNERRORCALLBACK)(ERRORMSGTYPE, char*); ERRORMSGTYPE是一个枚举 enum ERRORMSGTYPE
{
ERRORMSG_INFO,
ERRORMSG_WARNING,
ERRORMSG_ERROR,
ERRORMSG_FATAL
};
我使用vb调用该函数,vb中声明这样写Declare Function registerErrorMessage Lib "B2BAPIDLL.dll" (ByVal pfnErrorMessage As Long) As Long回调函数这样写Public Sub ErrorMessageCallback(enErrorType As ERRORMSGTYPE, lpszMsg As Long)
Debug.Print lpszMsg
Call Form1.UpdateErrorMessage(enErrorType, lpszMsg)
End Sub其中ERRORMSGTYPE为枚举结构Public Enum ERRORMSGTYPE
ERRORMSG_INFO
ERRORMSG_WARNING
ERRORMSG_ERROR
ERRORMSG_FATAL
End Enum但是在调试的时候,每当我跟踪岛回调函数,想看enErrorType 变量值时,都会发送访问出错,我想问一下其中发生了什么事
{
ERRORMSG_INFO,
ERRORMSG_WARNING,
ERRORMSG_ERROR,
ERRORMSG_FATAL
};
我使用vb调用该函数,vb中声明这样写Declare Function registerErrorMessage Lib "B2BAPIDLL.dll" (ByVal pfnErrorMessage As Long) As Long回调函数这样写Public Sub ErrorMessageCallback(enErrorType As ERRORMSGTYPE, lpszMsg As Long)
Debug.Print lpszMsg
Call Form1.UpdateErrorMessage(enErrorType, lpszMsg)
End Sub其中ERRORMSGTYPE为枚举结构Public Enum ERRORMSGTYPE
ERRORMSG_INFO
ERRORMSG_WARNING
ERRORMSG_ERROR
ERRORMSG_FATAL
End Enum但是在调试的时候,每当我跟踪岛回调函数,想看enErrorType 变量值时,都会发送访问出错,我想问一下其中发生了什么事
Public Sub ErrorMessageCallback(ByVal enErrorType As ERRORMSGTYPE,ByVal lpszMsg As Long)
End Sub
ERRORMSG_INFO,但是我在vb跟踪回调函数enErrorType得到值是3,另外lpszMsg 字段
为错误描述字符串地址,vb怎么才能取得其内容
Public Function StrFromPtr(ByVal lpString As Long) As String
On Error Resume Next
StrFromPtr = String(1024, Chr(0))
CopyMemory ByVal StrFromPtr, ByVal lpString, Len(StrFromPtr)
StrFromPtr = Left(StrFromPtr, InStr(StrFromPtr, Chr(0)) - 1)
End Function
1:setenv()
2:registerRateUpdate(PFNRATECALLBACK pfnRateConsumer)
3:registerErrorMessage(PFNERRORCALLBACK pfnErrorMessage)
4:ReportMessage(ERRORMSGTYPE enErrorType, char* szMsg);
前三个都是export的函数,第四个的定义是这样
ReportMessage(ERRORMSGTYPE enErrorType, char* szMsg)
{
if (m_pfnErrorCallback)
m_pfnErrorCallback(enErrorType, szMsg);
}
其中m_pfnErrorCallback是PFNERRORCALLBACK 类型回调函数
dll中setenv和registerRateUpdate函数体内都会调用多个ReportMessage报告运行信息。
在vb程序中,我在sub main调用registerErrorMessage后,跟踪dll执行到首个ReportMessage
时m_pfnErrorCallback是我在vb里写的回调函数,但是跟踪到第二个ReportMessage就报告内存读写错误信息了
dll源码,m_pfnErrorCallback在第一次ReportMessage结束,地址就变了,不知道为什么
用vc调用跟踪时在ReportMessage里this变量总是同一个地址,用vb调用跟踪时ReportMessage
里在回调函数结束后this的地址值变了,然后pfnErrorCallback这个地址也不合法了,是不是dll的静态动态问题
// B2B_API.h : interface definition
//#if !defined(AFX_B2B_API_H__B5E847A3_1251_11D5_A662_0008C7E19073__INCLUDED_)
#define AFX_B2B_API_H__B5E847A3_1251_11D5_A662_0008C7E19073__INCLUDED_#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifdef B2BAPI
#define B2B_API __declspec(dllexport)
#else
#define B2B_API __declspec(dllimport)
#endif
#define B2B_APIV __stdcallextern "C"
{
// Trade result type
enum TRADERESULTTYPE
{
TRADERESULT_SUCCESS,
TRADERESULT_FAIL,
TRADERESULT_JNIERROR,
TRADERESULT_UNKNOWN
}; // Error message type
enum ERRORMSGTYPE
{
ERRORMSG_INFO,
ERRORMSG_WARNING,
ERRORMSG_ERROR,
ERRORMSG_FATAL
}; // Define structures
struct B2B_API B2B_SpotRate
{
char szID[33];
char szRateName[7];
long lValueDate;
double dblBid;
double dblAsk;
long lBidLimit;
long lAskLimit;
char szLimitCcy[4];
BOOL fTradable;
int nTicksize;
int nDisplayDecs;
long lTimestamp;
long lServerTimestamp;
}; struct B2B_API B2B_Status
{
BOOL fConnected;
BOOL fConnectedToServer; // Use this flag for connection status
};
struct B2B_API B2B_TradeResult
{
TRADERESULTTYPE enResult;
char szReason[20];
char szTradeID[10];
};
// Callback types
typedef void (*PFNRATECALLBACK)(B2B_SpotRate*);
typedef void (*PFNSTATUSCALLBACK)(B2B_Status*);
typedef void (*PFNERRORCALLBACK)(ERRORMSGTYPE, char*);
// API calls
BOOL B2B_APIV startJVM();
BOOL B2B_APIV registerRateUpdate(PFNRATECALLBACK pfnRateConsumer);
BOOL B2B_APIV registerStatusUpdate(PFNSTATUSCALLBACK pfnPropertyChangeListener);
BOOL B2B_APIV registerErrorMessage(PFNERRORCALLBACK pfnErrorMessage);
BOOL B2B_APIV deregisterRateUpdate();
BOOL B2B_APIV deregisterStatusUpdate();
BOOL B2B_APIV tradeSpot(double dblAmount,
double dblTradedRate,
char cBuySell,
char cLeftRight,
char* szID,
char* szRef,
char* szCustomer,
B2B_TradeResult* pTradeResult);}
#endif // !defined(AFX_B2B_API_H__B5E847A3_1251_11D5_A662_0008C7E19073__INCLUDED_)
回调函数,我想在这个时候只要exe不退出dll里面的回调函数地址应该不会变,然后用
按钮触发STARTJVM()设定环境,STARTJVM里面调用多个REPORTMESSAGE报告情况,顺序基本上就是这个样子了
-->
typedef void (__stdcall *PFNRATECALLBACK)(B2B_SpotRate*);……