2017-06-29 61 views
1

所以我有一个引用DLL的主程序(在单独的解决方案中)。下面是设计代码:C++静态向量在DLL中丢失元素

//.h of DLL 

#ifdef DLL_PREPRO 
    #define DLL_LINK __declspec(dllexport) 
#else 
    #define DLL_LINK __declspec(dllimport) 
#endif 

enum MyID 
{ 
    //values here.... 
} 

DLL_LINK class MyCustomClass 
{ 
public: 
    MyID id; 
    LPCTSTR lpszApp; 
    LPCTSTR lpszKey; 
    LPCTSTR lpszDefault; 
    CString& strData; 
} 

static vector<MyCustomClass> m_customClass; //the vector in question 

DLL_LINK void InitTables(); 

//I have other custom classes that has almost similar structure to this, and with their corresponding vector 
//on the .cpp is the implementation of function InitTables() that is called by the EXE side wherein I am doing some processing on the vectors 

//.cpp on the EXE side 

void AddCustomClass(MyCustomClass c) 
{ 
    (&m_customClass)->push_back(c); 
} 

//I have another method here who populates the vector by calling AddCustomClass repeatedly 

我的问题是,在调试过程中,在EXE边我看到越来越填充载体(我用“添加到watch'-ING每个向量做到这一点),但是当我步超过(F10)到dll端的InitTables函数,所有向量现在包含0个元素。 顺便说一下,我拖动DLL的cpp文件的exe解决方案,以便能够设置断点。 由于使用空元素访问这些向量会引发错误,因此我暂时在InitTables()函数之上放置了一个返回值。然后,当我F10再次回到在exe解决方案中的下一行时,所有的载体现在有他们的元素回

所以我的问题是,什么是错误的设计/源代码,应如何纠正?谢谢!

+0

这两个项目是用完全相同的MSVC版本和完全相同的选项构建的吗? MSVC不保证版本之间的C++ ABI兼容性,并且编译选项差异也会破坏ABI。 –

+0

两者都是在VS2010 pro中构建的,但我认为两者的项目属性存在一些差异。 _Background:_之前只有1个程序 - 将其他项目中使用的部分分隔为一个DLL。 –

+0

背景:MSVC已经改变了版本之间标准库集合(和其他类)的内部布局。因此,通过使用不同版本构建的模块传递标准库类可以提供您正在看到的效果。 –

回答

2

问题是,你已经使用keywork静态在头文件:

static vector<MyCustomClass> m_customClass; //the vector in question 

在这种情况下静态装置:该符号仅在当前单元是可见的。 因此,包含这个头文件的每个.cpp文件都有自己的这个全局变量的实例!实际上,你可以有10个这个变量的实例。

也许你想是这样的:

extern DLL_LINK vector<MyCustomClass> m_customClass; 

而且在各自的.cpp文件只需添加:

vector<MyCustomClass> m_customClass; 
+0

我试过你说的,但它给了我错误LNK2001无法解析的外部符号。从我的理解,它需要看到包含实际声明的cpp文件,但在我的情况是,错误在DLL部分,它是什么被引用。我应该如何处理这个问题? –

+0

抱歉忘了一个部分,请参阅答案更新。 extern只是说“它是变量的声明”,所以它的定义丢失了。 –

+0

让我来澄清一下:我是否应该在EXE中的cpp中extern这个DLL,还是你的意思是在DLL里面有一些其他的cpp?我很抱歉抱歉。 –

0

static符在命名空间范围的变量赋予变量内部联动。从根本上说,这意味着每个.cpp文件都将拥有自己的这种变量副本。显然不是你想要的。如果你想在DLL中定义变量但是从EXE访问变量,它实际上必须是extern(和导出),而不是static