问题
I have a weird problem when I create a release build with Visual Studio 2008. I was wondering if one of you could help me understand what is going on.
Description: I have a class member function which returns a pointer to a structure stored in the class:
const MyStruct * Myclass::getPointer() {
return mystruct_variable; // this is properly initialyzed
}
One another point worth pointing out is that this class/method is in a dll, and I export it to use in a separate executable project. When I make a release build and try to use the above mentioned method, the run crashes depending on if the getPointer() method is inlined (i.e. placed in the header file part of the class) or not (placed in the cpp file).
The usage is:
const MyStruct * cf = myclassObj.getPointer();
int n = cf->size_t;
std::cout<<n<<std::endl;
When MyClass::getPointer() is inlined in the header the assembly looks like:
const MyStruct * cf = myclassObj.getPointer();
012514A8 mov esi,dword ptr [ebx+794h]
int n =cf->size_t;
012514AE mov eax,dword ptr [esi+20h]
std::cout<<n<<std::endl;
012514B1 mov ecx,dword ptr [__imp_std::endl (1252038h)]
012514B7 push ecx
012514B8 mov ecx,dword ptr [__imp_std::cout (125203Ch)]
012514BE push eax
012514BF call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (1252048h)]
012514C5 mov ecx,eax
012514C7 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (1252044h)]
The same code when the class method for getPointer() is not inlined, and placed in the corresponding cpp file gives:
const MyStruct * cf = myclassObj.getPointer();
00DA14A8 mov ecx,ebx
00DA14AA call dword ptr [__imp_MyClass::getPointer(0DA2104h)]
int n =cf->size_t;
std::cout<<n<<std::endl;
00DA14B0 mov ecx,dword ptr [__imp_std::endl (0DA2038h)]
00DA14B6 mov esi,eax
00DA14B8 mov eax,dword ptr [esi+20h]
00DA14BB push ecx
00DA14BC mov ecx,dword ptr [__imp_std::cout (0DA203Ch)]
00DA14C2 push eax
00DA14C3 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0DA2048h)]
00DA14C9 mov ecx,eax
00DA14CB call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0DA2044h)]
Any thoughts why the two cases have different assembly set? Am I doing something wrong? Thanks!
回答1:
If you link against a C++ DLL you must make sure all the compiler flags are exactly the same. Otherwise the size of structures, virtual tables etc. might be different and the code fails with an invalid access to memory. Inlining of course overcomes this as the code is inside the exe file, not in the dll, and thus compiled with the correct flags.
Simply put - for a release build use release DLL, for a debug build use debug DLL.
来源:https://stackoverflow.com/questions/11592775/pointers-and-release-build-in-visual-studio