因为需要写一些DLL,且DLL编译选择/MT方式,DLL会导出函数,函数中会返回指针。
如下所示:(示例仅供参考,呵呵)
int * WINAPI Export()
{
return new int;
}
现在我的EXE中会使用这个函数,代码如下:(如何获取函数地址的方法我就不赘述)
int *p = Export();
然后我在使用完后我直接在EXE中调用 delete p,此时会发生异常,报访问异常。后来想了一下,这个异常有一些道理,因为不是EXE中申请的内存。所以,我又在上面的DLL中导出了一个函数,如下所示:
void WINAPI Destory(int *p)
{
delete p;
}
然后在EXE中调用此函数,但程序依旧发生异常,报访问异常,着实想不通。后来查了一通资料,在http://msdn.microsoft.com/en-us/library/ms235460.aspx中看出了一些端倪,然后使用/MD编译DLL和EXE,一切正常,说明程序没有任何问题,是由/MT编译带来的问题。
后来想到使用VirtualAlloc这个函数来分配内存,同时使用VirtualFree来释放内存,经过测试,使用/MT编译DLL和EXE一切正常。
说到这里,肯定会有人,那对于自定义类型(即类)如何做呢?也即我导出的是一个对象指针,不是一个内置的对象指针,如何做呢?
我目前试了一下,代码如下:
class KWhat
{
public:
KWhat(){}
BOOLinit()
{
m_iWhat= 0;
returnTRUE;
}
private:
intm_iWhat;
};
extern "C" __declspec(dllexport) int *GetPointer()
{
PVOIDpv = VirtualAlloc(NULL,1024,MEM_COMMIT,PAGE_READWRITE);
KWhataa;
memcpy(pv,&aa,sizeofaa);
((KWhat*)pv)->init();
return(int*)pv;
}
extern "C" __declspec (dllexport) void Destory(int *p)
{
VirtualFree((void*)p,1024,PAGE_READWRITE);
}
EXE中调用这二个方法,没有问题。至此,跨DLL边界传递指针对象算是找到一个变通的方法实现,但不知道是否还有其他方法来实现。
为什么有多份CRT库的拷贝时,就不能直接delete对象呢?为什么要这样实现,期待更多的人来讨论这个问题。