指针和发布版本在Visual Studio中 [英] Pointers and release build in Visual Studio

查看:93
本文介绍了指针和发布版本在Visual Studio中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用Visual Studio 2008创建发行版本时,我遇到了一个奇怪的问题.我想知道你们中的一个人是否可以帮助我了解正在发生的事情.

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 
}

值得指出的另一点是,此类/方法在dll中,我将其导出以在单独的可执行项目中使用.当我进行发行版本构建并尝试使用上述方法时,运行会崩溃,具体取决于是否将getPointer()方法内联(即放置在类的头文件部分中)或不进行内联(放置在cpp文件中).

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).

用法是:

const MyStruct * cf = myclassObj.getPointer();
int n = cf->size_t;
std::cout<<n<<std::endl;

在标头中内联MyClass :: getPointer()时,程序集如下所示:

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)] 

当未内联getPointer()的类方法并将其放置在相应的cpp文件中时,相同的代码给出:

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!

推荐答案

如果针对C ++ DLL进行链接,则必须确保所有编译器标志完全相同.否则,结构,虚拟表等的大小可能会有所不同,并且代码将因对内存的无效访问而失败.内联当然可以解决此问题,因为代码位于exe文件中,而不是dll中,因此可以使用正确的标志进行编译.

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.

简单地说-对于发行版,请使用发行版DLL,对于调试版,请使用调试DLL.

Simply put - for a release build use release DLL, for a debug build use debug DLL.

这篇关于指针和发布版本在Visual Studio中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆