Visual Studio中的指针和发布版本

Pointers and release build in Visual Studio

本文关键字:布版本 版本 Studio 指针 Visual      更新时间:2023-10-16

我在使用Visual Studio 2008创建发布版本时遇到了一个奇怪的问题。我想知道你们中是否有人能帮我了解发生了什么

说明:我有一个类成员函数,它返回一个指向存储在类中的结构的指针:

const MyStruct * Myclass::getPointer() { 
    return mystruct_variable; // this is properly initialyzed 
}

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

用法是:

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

当MyClass::getPointer()内联在标头中时,程序集看起来像:

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文件中时,相同的代码给出:

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

有什么想法为什么这两个案例有不同的集合吗?我做错什么了吗?谢谢

如果链接到C++DLL,则必须确保所有编译器标志都完全相同。否则,结构、虚拟表等的大小可能会不同,并且代码会因对内存的无效访问而失败。内联当然克服了这一点,因为代码在exe文件中,而不是在dll中,因此使用正确的标志进行编译。

简单地说,对于发布版本使用发布DLL,对于调试版本使用调试DLL。