c++ - Visual Studio 中的指针和发布版本

标签 c++ visual-studio pointers assembly inline-assembly

当我使用 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() 内联在 header 中时,程序集如下所示:

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

为什么这两个案例有不同的 assembly 集?难道我做错了什么? 谢谢!

最佳答案

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

简单地说 - 对于发布构建使用发布 DLL,对于调试构建使用调试 DLL。

关于c++ - Visual Studio 中的指针和发布版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11592775/

相关文章:

c++ - 无效使用不完整类型 'PGconn {aka struct pg_conn}'

visual-studio - 在 Visual Studio 中将 DLL 与 Qt 一起使用

c - 如何在 C 中使错误的指针算术更加明显?

c - C 中 scanf 函数中的字符数组指针没有 & 符号

c - signal_connect 函数中的指针工作不正常

c++ - 绑定(bind)错误 "The C++ Programming Language [4th Edition] - Bjarne Stroustrup"

c++ - 计算合并排序算法的交换/比较次数

c++ - 使用2D数组存储天气数据。 C++

visual-studio - 针对Visual Studio多个版本的DebuggingVisualizer

c++ - 为什么我的程序在 64 GB RAM 系统上占用的内存不超过 2 GB?