这种问题,在编译的时候是不会出现问题的,但是在运行时就会崩溃,
例如 接口 来至A.dll
#define MAX_LINE 255
struct _ttt
{
_ttt()
{
memset(a,0,MAX_LINE*sizeof(TCHAR));
memset(b,0,MAX_LINE*sizeof(TCHAR));
memset(c,0,MAX_LINE*sizeof(TCHAR));
}
TCHAR a[MAX_LINE];
TCHAR b[MAX_LINE];
TCHAR c[MAX_LINE];
};
typedef CArray<_ttt,_ttt&> CArrayTTT;
extern __declspec(dllexport) void Fun(LPCTSTR pszFilePath, CArrayTTT& arr);
(这里的pszFilePath 是一个文件路径,这个没什么问题,arr是传入在传出的参数,就是在接口里面会有数据往里面添加)
在另外一个exe工程里调用 A.dll 中的接口Fun
{
CArrayTTT arr;
CString sFilePath = _T("a.txt");
Fun(sFilePath,arr);
}
到这里应该编译连接都没问题,但是在运行到这段代码的时候,出了右边的大括号就会崩溃,提示在_CrtIsValidHeapPointer函数里异常,
这说明什么:说明在释放局部变量内存的时候出现了问题,查找相关资料得知(例如MSDN),dll中的数据堆栈是独立的,跟当前应用程序是分开的,在当前应用程序中释放dll中的堆栈空间是不对的,原因就是你把dll堆栈空间中的地址当成当前应用程序中的堆栈空间中的地址了,这段话说的我也是醉了,慢慢理解吧,反正这样是不允许的。
如何解决这种问题呢,如果把dll和调用dll的堆栈空间区分开来处理,就不会出现这种问题了,就上面的例子 把 接口改下:我这里这样改的(也可以有其他更好的方法来处理)
extern __declspec(dllexport) void Fun(LPCTSTR pszFilePath, CArrayTTT*& pArr);
参数 pArr 的内存在dll中申请
void Fun(LPCTSTR pszFIlePath, CArrayTTT*& pArr)
{
.....
pArr = new CArrayTTT();
....
}
当然 申请了内存就别忘了释放
extern __declspec(dllexport) void ReleaseMem( CArrayTTT* pArr);
void ReleaseMem(CArrayTTT* pArr)
{
if(pArr != NULL)
{
delete pArr;
pArr = NULL;
}
}
在调用 Fun接口的应用程序中就得这样来用了:
{
CArrayTTT* pArr;
CString sFilePath = _T("a.txt");
Fun(sFilePath,pArr);
ReleaseMem(pArr);
}
当然你也可以有其他的方法解决这种问题,只要思想是对的,问题总能通过不同的方法来处理掉。