下面的C++接口,我用DELPHI对接,调用时报内存异常,麻烦各位大侠帮忙看一下:C++接口定义:struct STUMsgProperty 2 {
char m_szSourceUserID[MR 2_MAXLEN_ADDR];
char m_szSourceAppID[MR 2_MA XLEN_ADDR];
char m_szDestUserID[MR 2_MAXLEN_ADDR];
char m_szDestAppID[MR 2_MAXLEN_ADDR];
char m_szPkgID[MR 2_MAXLEN_PKGID];
char m_szCorrPkgID[MR 2_MAXLEN_PKGID];
char m_szUserData 1[MR 2_MAXLEN_USERDATA];
char m_szUserData2[MR 2_MAXLEN_USERDATA];
unsigned char m_ucFlag;
unsigned char m_uc Biz Type;
unsigned char m_ucPriority;
unsigned char m_ucSensitiveLevel;
char m_szMsgType[MR2_MAXLEN_MSGTYPE];
};int _stdcall Mr 2Receive3(void* pHandle, char** ppsPkg, int * piOutPkgLen, int* piErrSXCode, STUMsgProperty 2* pMsgPropery, int iMillSecTimeo) ;
参数 说明
pHandle [in] 连接句柄。
ppsPkg [out] 双指针,返回包所向的内存。
piOutPkgLen [out] 接收到的消息包实际长度。
piErrSXCode[out] 交换错误的原因码.
pMsgPropery [in/out] 输入将作为接收条件,输出是接收到的包属性。
iMillSecTimeo [in] 以毫秒为单位的接收最大时间。Delphi代码:type
pSTUMsgProperty2 = ^TSTUMsgProperty2;
TSTUMsgProperty2 = record
m_szSourceUserID: array[1..MR2_MAXLEN_ADDR] of AnsiChar;
m_szSourceAppID: array[1..MR2_MAXLEN_ADDR] of AnsiChar;
m_szDestUserID: array[1..MR2_MAXLEN_ADDR] of AnsiChar;
m_szDestAppID: array[1..MR2_MAXLEN_ADDR] of AnsiChar;
m_szPkgID: array[1..MR2_MAXLEN_PKGID] of AnsiChar;
m_szCorrPkgID: array[1..MR2_MAXLEN_PKGID] of AnsiChar;
m_szUserData1: array[1..MR2_MAXLEN_USERDATA] of AnsiChar;
m_szUserData2: array[1..MR2_MAXLEN_USERDATA] of AnsiChar;
m_ucFlag: word;
m_ucBizType: word;
m_ucPriority: word;
m_ucSensitiveLevel: word;
m_szMsgType: array[1..MR2_MAXLEN_MSGTYPE] of AnsiChar;
end;type
TMr2RecvFunc = function(_pMr2InitHandle: PHandle; const ppsPkg: PPAnsiChar; piOutPkgLen: Pinteger; piErrSXCode: Pinteger; pMsgPropery: pSTUMsgProperty2; iMillSecTimeo: integer):integer;stdcall;function Mr2Receive: Integer;
var
pMr2Recv: TMr2RecvFunc;
FileStream: TFileStream;
FileBuffer: PPAnsiChar;
piOutPkgLen, piErrSXCode: pinteger;
pMsgPropery: pSTUMsgProperty2;
MsgPropery: TSTUMsgProperty2;
begin
Result := -1; if pMr2InitHandle = nil then
begin
ShowMessage('请先初始化Mr2!');
Exit;
end; if not Assigned(@pMr2Recv) then
@pMr2Recv := GetProcAddress(Mr2Handle, 'Mr2Receive3'); if Assigned(@pMr2Recv) then
begin
new(pMsgPropery);
Result := pMr2Recv(pMr2InitHandle, FileBuffer,piOutPkgLen, piErrSXCode, pMsgPropery, 2000);//这一步报内存写异常
Dispose(pMsgPropery);
end;
end;
char m_szSourceUserID[MR 2_MAXLEN_ADDR];
char m_szSourceAppID[MR 2_MA XLEN_ADDR];
char m_szDestUserID[MR 2_MAXLEN_ADDR];
char m_szDestAppID[MR 2_MAXLEN_ADDR];
char m_szPkgID[MR 2_MAXLEN_PKGID];
char m_szCorrPkgID[MR 2_MAXLEN_PKGID];
char m_szUserData 1[MR 2_MAXLEN_USERDATA];
char m_szUserData2[MR 2_MAXLEN_USERDATA];
unsigned char m_ucFlag;
unsigned char m_uc Biz Type;
unsigned char m_ucPriority;
unsigned char m_ucSensitiveLevel;
char m_szMsgType[MR2_MAXLEN_MSGTYPE];
};int _stdcall Mr 2Receive3(void* pHandle, char** ppsPkg, int * piOutPkgLen, int* piErrSXCode, STUMsgProperty 2* pMsgPropery, int iMillSecTimeo) ;
参数 说明
pHandle [in] 连接句柄。
ppsPkg [out] 双指针,返回包所向的内存。
piOutPkgLen [out] 接收到的消息包实际长度。
piErrSXCode[out] 交换错误的原因码.
pMsgPropery [in/out] 输入将作为接收条件,输出是接收到的包属性。
iMillSecTimeo [in] 以毫秒为单位的接收最大时间。Delphi代码:type
pSTUMsgProperty2 = ^TSTUMsgProperty2;
TSTUMsgProperty2 = record
m_szSourceUserID: array[1..MR2_MAXLEN_ADDR] of AnsiChar;
m_szSourceAppID: array[1..MR2_MAXLEN_ADDR] of AnsiChar;
m_szDestUserID: array[1..MR2_MAXLEN_ADDR] of AnsiChar;
m_szDestAppID: array[1..MR2_MAXLEN_ADDR] of AnsiChar;
m_szPkgID: array[1..MR2_MAXLEN_PKGID] of AnsiChar;
m_szCorrPkgID: array[1..MR2_MAXLEN_PKGID] of AnsiChar;
m_szUserData1: array[1..MR2_MAXLEN_USERDATA] of AnsiChar;
m_szUserData2: array[1..MR2_MAXLEN_USERDATA] of AnsiChar;
m_ucFlag: word;
m_ucBizType: word;
m_ucPriority: word;
m_ucSensitiveLevel: word;
m_szMsgType: array[1..MR2_MAXLEN_MSGTYPE] of AnsiChar;
end;type
TMr2RecvFunc = function(_pMr2InitHandle: PHandle; const ppsPkg: PPAnsiChar; piOutPkgLen: Pinteger; piErrSXCode: Pinteger; pMsgPropery: pSTUMsgProperty2; iMillSecTimeo: integer):integer;stdcall;function Mr2Receive: Integer;
var
pMr2Recv: TMr2RecvFunc;
FileStream: TFileStream;
FileBuffer: PPAnsiChar;
piOutPkgLen, piErrSXCode: pinteger;
pMsgPropery: pSTUMsgProperty2;
MsgPropery: TSTUMsgProperty2;
begin
Result := -1; if pMr2InitHandle = nil then
begin
ShowMessage('请先初始化Mr2!');
Exit;
end; if not Assigned(@pMr2Recv) then
@pMr2Recv := GetProcAddress(Mr2Handle, 'Mr2Receive3'); if Assigned(@pMr2Recv) then
begin
new(pMsgPropery);
Result := pMr2Recv(pMr2InitHandle, FileBuffer,piOutPkgLen, piErrSXCode, pMsgPropery, 2000);//这一步报内存写异常
Dispose(pMsgPropery);
end;
end;
解决方案 »
- (新手)通过query利用SQL语句把数据库的数据读到EDIT控件?
- 急---字符编码问题---200分求解
- 怎么判断系统空闲(长时间无键盘和鼠标操作)? 就像MSN发现你不在和回来那样
- 出错信息:invalid language driver!高分求教?
- 找不到的软件
- 怎样发送按下"F6"键这个消息给一个已知句柄??
- 兄弟姐妹们请帮帮我★★★★★★★★★★★★★★★★★★★★★★★★。。。。。。。。。。。。。。。。
- 怎样使软件加密?
- ◎◎◎可有提供打印功能的 DBGrid 控件???
- 关于WebServer的问题。
- DSPACK控件,实现用摄像头录像后,视频上有摄像的时间(读电脑的日期时间)
- TEdit在真机上输入时闪退!都遇到过没有?
赋值有什么要注意的么?
TMr2RecvFunc = function(_pMr2InitHandle: PHandle; var ppsPkg: PAnsiChar; var piOutPkgLen: integer; var piErrSXCode: integer; var pMsgPropery: TSTUMsgProperty2; iMillSecTimeo: integer):integer;stdcall; function Mr2Receive: Integer;
var
pMr2Recv: TMr2RecvFunc;
FileBuffer: PAnsiChar;
piOutPkgLen, piErrSXCode: integer;
MsgPropery: TSTUMsgProperty2;
begin
Result := -1; if not Assigned(@pMr2Recv) then
@pMr2Recv := GetProcAddress(Mr2Handle, 'Mr2Receive3'); if Assigned(@pMr2Recv) then
begin
GetMem(FileBuffer,4096);
new(pMsgPropery);
try
Result := pMr2Recv(pMr2InitHandle, FileBuffer,piOutPkgLen, piErrSXCode, MsgPropery, 2000);
except end;
freeMem(FileBuffer);
Dispose(pMsgPropery);
end;end;上面的代码还是报错,是初始化有问题么?
pMr2InitHandle是全局变量,已经有值的。
pMr2InitHandle = pMr2Init(ConfigMsg.AppID, ConfigMsg.AppPasswd, nil, @ConfigMsg.STUConnInfo, 2, PAnsiChar(''));
是的,发送数据、断开连接的接口都需要用到这个值,调用时没有发现问题。
但是我用pMr2InitHandle^取到的值是1,不知道是什么原因。
以下蓝色部分是C++的DEMO,用的MR2RECEIVE1:
typedef int (WINAPI MR2RECEIVE1)(void*, char**, int*, STUMsgProperty2*, int);
typedef int (WINAPI MR2RECEIVE3)(void*, char**, int*, int*, STUMsgProperty2*, int);unsigned __stdcall RecvThrd(void *pvParam)
{
int iLastGetOk = 0;
for(;;)
{
STUMsgProperty2 oMsgPropery;
memset(&oMsgPropery, '\0', sizeof(STUMsgProperty2)); int iRecvPkgLen = 0;
char* psPkg = NULL;
int iRet = Mr2Receive1(g_pHandle, &psPkg, &iRecvPkgLen, &oMsgPropery, 1000);
if(iRet==0)
{
g_ltLastTimeRecv = time(NULL);
++g_iRecvCount;
if(g_iRecvCount%100==0)
{
printf("recv ok: PkgContent[%s]\n, pkgID[%s], src[%s.%s], dest[%s.%s], pkgLen[%d], CorrPkgID[%s], UserData1[%s], UserData2[%s] \n", psPkg, oMsgPropery.m_szPkgID, oMsgPropery.m_szSourceUserID, oMsgPropery.m_szSourceAppID, oMsgPropery.m_szDestUserID, oMsgPropery.m_szDestAppID, iRecvPkgLen, oMsgPropery.m_szCorrPkgID, oMsgPropery.m_szUserData1, oMsgPropery.m_szUserData2);
printf("client recv count[%d]\n", g_iRecvCount);
}#ifndef MR_CLIENT
STUMsgProperty2 oMsgProperySend;
memset(&oMsgProperySend, '\0', sizeof(STUMsgProperty2));
strcpy(oMsgProperySend.m_szDestUserID, oMsgPropery.m_szSourceUserID);
strcpy(oMsgProperySend.m_szDestAppID, oMsgPropery.m_szSourceAppID);
strcpy(oMsgProperySend.m_szCorrPkgID, oMsgPropery.m_szPkgID);
strcpy(oMsgProperySend.m_szUserData1, oMsgPropery.m_szUserData1);
strcpy(oMsgProperySend.m_szUserData2, oMsgPropery.m_szUserData2);
oMsgProperySend.m_ucFlag = 0;
int iRet = Mr2Send(g_pHandle, psPkg, iRecvPkgLen, &oMsgProperySend, 2000);
#endif
Mr2Receive1_FreeBuf(psPkg);
}
else
{
MySleep(500);
}
}
return 0;
}我现在想在DELPHI里调用MR2RECEIVE3,跟MR2RECEIVE1比就多了一个参数,麻烦再帮忙看一下哈。
int iRet = Mr2Receive1(g_pHandle, &psPkg, &iRecvPkgLen, &oMsgPropery, 1000);
那么:
TMr2RecvFunc = function(_pMr2InitHandle: pointer; var ppsPkg: PAnsiChar; var piOutPkgLen: integer; var piErrSXCode: integer; var pMsgPropery: TSTUMsgProperty2; iMillSecTimeo: integer):integer;stdcall;
谢谢!真的很着急。
只是这个
int iRet = Mr2Receive1(g_pHandle, &psPkg, &iRecvPkgLen, &oMsgPropery, 1000);
g_pHandle是怎么得到的还得看他的例子代码,可能是你获取的不对。
这个是C++ DEMO中的初始化过程:
typedef void *(WINAPI MR2INIT)(const char*, const char*, int, const STUConnInfo2*, void *);
void* g_pHandle = NULL;int main(int argc, char* argv[])
{
if (!LoadDll())
{
printf("load mrapi.dll error.\n");
return -1;
}
string ssSourceUserID, ssSourceAppID, ssDestUserID, ssDestAppID;
string ssName1 = "FTCSTEST91";
string ssName2 = "app8";
string ssName3 = "FTCSTEST92";
string ssName4 = "app6";
#ifdef MR_CLIENT
ssSourceUserID = ssName1;
ssSourceAppID = ssName2;
ssDestUserID = ssName3;
ssDestAppID = ssName4;
#else
ssSourceUserID = ssName3;
ssSourceAppID = ssName4;
ssDestUserID = ssName1;
ssDestAppID = ssName2;
#endif g_ltLastTimeRecv = time(NULL); string ssMyPasswd = "1";
string *pUserData = new string("hello"); STUConnInfo2 oConnInfo[2];
memset(&oConnInfo, 0, 2*sizeof(STUConnInfo2));
if(argc<2) strcpy(oConnInfo[0].m_szMRIP, "127.0.0.1");
else strcpy(oConnInfo[0].m_szMRIP, argv[1]);
oConnInfo[0].m_usMRPort = 1001;
strcpy(oConnInfo[1].m_szMRIP, "127.0.0.1");
oConnInfo[1].m_usMRPort = 3001; g_pHandle = Mr2Init(ssSourceAppID.c_str(), ssMyPasswd.c_str(), NULL, &oConnInfo, 2, pUserData);
if(g_pHandle==NULL) return -1;
/*
STUMsgProperty2 oOnRecvMsgPropery;
memset(&oOnRecvMsgPropery, 0, sizeof(STUMsgProperty2));
strcpy(oOnRecvMsgPropery.m_szCorrPkgID, "<EMPTY>");
Mr2Init2(&g_pHandle, ssSourceAppID.c_str(), ssMyPasswd.c_str(), &oOnRecvMsgPropery, (int)OnReceive, &oConnInfo, 2, pUserData, 1);
if(g_pHandle==NULL) return -1;*/
if(_beginthreadex(NULL, 0, RecvThrd, NULL, 0, NULL)==0)
{
printf("create thread failed\n");
return -1;
} printf("\n");
MySleep(2000);
g_ltLastTimeRecv = time(NULL);#ifdef MR_CLIENT
#else for(;;MySleep(1000))
{
}
#endif Mr2Destroy(g_pHandle);
printf("End\n"); return 0;
}下面是DELPHI代码:
type TMr2InitFunc = function(const psAppID: PAnsiChar; const psPasswd:PAnsiChar; OnReceive:PInteger; const pArrConnInfo:pSTUConnInfo2; iArrConnInfoCount: Integer; pvUserData:PAnsiChar):Pointer;stdcall;function Mr2Init: Pointer;
var
pMr2Init: TMr2InitFunc;
begin
Result := nil; if Mr2Handle = 0 then
begin
PrintLog('请先加载mrapi.dll!');
Exit;
end; @pMr2Init := GetProcAddress(Mr2Handle, 'Mr2Init');
if Assigned(@pMr2Init) then
begin
GetConfigMsg;
Result := pMr2Init(ConfigMsg.AppID, ConfigMsg.AppPasswd, nil, @ConfigMsg.STUConnInfo, 2, PAnsiChar(''));
end;
end;
typedef void *(WINAPI MR2INIT)(const char*, const char*, int, const STUConnInfo2*, void *);
和实际调用
g_pHandle = Mr2Init(ssSourceAppID.c_str(), ssMyPasswd.c_str(), NULL, &oConnInfo, 2, pUserData);
对不上啊。type TMr2InitFunc = function(const psAppID: PAnsiChar; const psPasswd:PAnsiChar; OnReceive:PInteger; const pArrConnInfo:pSTUConnInfo2; iArrConnInfoCount: Integer; pvUserData:PAnsiChar):Pointer;stdcall;
是根据什么翻译的?
void* _stdcall Mr2Init(const char* psAppID, const char* psPasswd, int (*OnRe ceive 2)(const char* psPkg, int iPkgLe n, const STUMsgProperty 2* pMsgPropery , void* pvUserData), const STUConnInfo 2* pArrC onnInfo , int iArrConnInfoCount , void* pvUserData);int _stdcall Mr2Receive3(void* pHandle, char** ppsPkg, int * piOutPkgLen, int* piErrSXCode, STUMsgProperty 2* pMsgPropery, int iMillSecTimeo) ;2. C++ DEMO代码:
声明:
typedef void *(WINAPI MR2INIT)(const char*, const char*, int, const STUConnInfo2*, void *);
typedef int (WINAPI MR2RECEIVE3)(void*, char**, int*, int*, STUMsgProperty2*, int);
变量定义
MR2INIT *Mr2Init;
MR2RECEIVE3 *Mr2Receive3;
HINSTANCE m_ghDll;
void* g_pHandle = NULL;加载DLL
m_ghDll = ::LoadLibrary(MRAPI_DLL) ;
if (m_ghDll == NULL)
{
printf(“error: can not find (mrapi.dll).”) ;
return bRet ;
}
Mr2Init = (MR2INIT *)::GetProcAddress(m_ghDll, "Mr2Init") ;
if (Mr2Init == NULL)
{
printf(“error: can not find Mr2Init(mrapi.dll)”) ;
::FreeLibrary(m_ghDll) ;
m_ghDll = NULL ;
return bRet ;
}
Mr2Receive3 = (MR2RECEIVE3 *)::GetProcAddress(m_ghDll, "Mr2Receive3") ;
if (Mr2Receive3 == NULL)
{
printf(“error: can not find Mr2Receive3(mrapi.dll)”) ;
::FreeLibrary(m_ghDll) ;
m_ghDll = NULL ;
return bRet ;
}
主程序
string ssSourceUserID, ssSourceAppID, ssDestUserID, ssDestAppID;
string ssName1 = "FTCSTEST91";
string ssName2 = "app8";
string ssName3 = "FTCSTEST92";
string ssName4 = "app6";
#ifdef MR_CLIENT
ssSourceUserID = ssName1;
ssSourceAppID = ssName2;
ssDestUserID = ssName3;
ssDestAppID = ssName4;
#else
ssSourceUserID = ssName3;
ssSourceAppID = ssName4;
ssDestUserID = ssName1;
ssDestAppID = ssName2;
#endif g_ltLastTimeRecv = time(NULL); string ssMyPasswd = "1";
string *pUserData = new string("hello"); STUConnInfo2 oConnInfo[2];
memset(&oConnInfo, 0, 2*sizeof(STUConnInfo2));
if(argc<2) strcpy(oConnInfo[0].m_szMRIP, "127.0.0.1");
else strcpy(oConnInfo[0].m_szMRIP, argv[1]);
oConnInfo[0].m_usMRPort = 1001;
strcpy(oConnInfo[1].m_szMRIP, "127.0.0.1");
oConnInfo[1].m_usMRPort = 3001; g_pHandle = Mr2Init(ssSourceAppID.c_str(), ssMyPasswd.c_str(), NULL, &oConnInfo, 2, pUserData);
if(g_pHandle==NULL) return -1;
/*
STUMsgProperty2 oOnRecvMsgPropery;
memset(&oOnRecvMsgPropery, 0, sizeof(STUMsgProperty2));
strcpy(oOnRecvMsgPropery.m_szCorrPkgID, "<EMPTY>");
Mr2Init2(&g_pHandle, ssSourceAppID.c_str(), ssMyPasswd.c_str(), &oOnRecvMsgPropery, (int)OnReceive, &oConnInfo, 2, pUserData, 1);
if(g_pHandle==NULL) return -1;*/
if(_beginthreadex(NULL, 0, RecvThrd, NULL, 0, NULL)==0)
{
printf("create thread failed\n");
return -1;
}
线程
unsigned __stdcall RecvThrd(void *pvParam)
{
int iLastGetOk = 0;
for(;;)
{
STUMsgProperty2 oMsgPropery;
memset(&oMsgPropery, '\0', sizeof(STUMsgProperty2)); int iRecvPkgLen = 0;
char* psPkg = NULL;
int iRet = Mr2Receive1(g_pHandle, &psPkg, &iRecvPkgLen, &oMsgPropery, 1000);
if(iRet==0)
{
g_ltLastTimeRecv = time(NULL);
++g_iRecvCount;
if(g_iRecvCount%100==0)
{
printf("recv ok: PkgContent[%s]\n, pkgID[%s], src[%s.%s], dest[%s.%s], pkgLen[%d], CorrPkgID[%s], UserData1[%s], UserData2[%s] \n", psPkg, oMsgPropery.m_szPkgID, oMsgPropery.m_szSourceUserID, oMsgPropery.m_szSourceAppID, oMsgPropery.m_szDestUserID, oMsgPropery.m_szDestAppID, iRecvPkgLen, oMsgPropery.m_szCorrPkgID, oMsgPropery.m_szUserData1, oMsgPropery.m_szUserData2);
printf("client recv count[%d]\n", g_iRecvCount);
}#ifndef MR_CLIENT
STUMsgProperty2 oMsgProperySend;
memset(&oMsgProperySend, '\0', sizeof(STUMsgProperty2));
strcpy(oMsgProperySend.m_szDestUserID, oMsgPropery.m_szSourceUserID);
strcpy(oMsgProperySend.m_szDestAppID, oMsgPropery.m_szSourceAppID);
strcpy(oMsgProperySend.m_szCorrPkgID, oMsgPropery.m_szPkgID);
strcpy(oMsgProperySend.m_szUserData1, oMsgPropery.m_szUserData1);
strcpy(oMsgProperySend.m_szUserData2, oMsgPropery.m_szUserData2);
oMsgProperySend.m_ucFlag = 0;
int iRet = Mr2Send(g_pHandle, psPkg, iRecvPkgLen, &oMsgProperySend, 2000);
#endif
Mr2Receive1_FreeBuf(psPkg);
}
else
{
MySleep(500);
}
}
return 0;
}
1. 接口文档定义(delph声明是根据这个来的):
void* _stdcall Mr2Init(const char* psAppID, const char* psPasswd, int (*OnRe ceive 2)(const char* psPkg, int iPkgLe n, const STUMsgProperty 2* pMsgPropery , void* pvUserData), const STUConnInfo 2* pArrC onnInfo , int iArrConnInfoCount , void* pvUserData);另外你编译一下他的C++ DEMO,看看能不能通过?我估计是不行的,因为函数声明和实际调用的参数个数都不一样嘛。
C++我没环境……看能不能想办法试试。