Click here to Skip to main content
15,868,040 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Using Visual Studio 2015 Community Edition.

I have a global object instantiated in a library. That object contains a vector of strings. That global object is accessed and used correctly without problems except under the following condition.

If a portion of application code not in the library throws an exception, the exception processing calls into that object, to access the vector of strings for reporting purposes.

C++
catch (Exception & e) {
   dwl::Globals * p = gDwlGlobals;  //Test to see if accessing gDwlGlobals this way fixes it.
   wStringStream s;  //For debugging, just to see if the address is same as previous
   s << p;           //quick way to print address to debug output
   OutputDebugString(s.str().c_str());
   const Strings & strings = gDwlGlobals->strings();  //See A.
   wString str = strings[Strings::Error_Programming]; //See B.
   ...
The OutputDebugString gives the same address for the global as the global showed during instantiation.

At (*A*) - In the debugger, the global address shows correctly on this line, and the 'strings' vector shows 79 elements in it through the dropdowns.

At (*B*) - The strings vector is now empty! And the enum offset throws an exception in my exception.

Any pointers?

What I have tried:

Everything I can think of except eliminating the library approach and seeing if making the solution into one project fixes it. (I think it will fix it, because I don't remember this error occurring before splitting it apart into a library. But I'd like to know why this isn't working.)

OK, I just tried eliminating the lib approach. As suspected, the error goes away. So the problem must be that the extern definitions are somehow not the same in the library and the non-library code, even though there is only one true non-extern definition. Any pointers on syncing lib pointers to the main application?
Posted
Updated 18-Oct-18 10:41am
Comments
CPallini 18-Oct-18 4:17am    
What is the 'strings' method signature?
David O'Neil 18-Oct-18 4:26am    
const Strings & strings() const { return stringsC; }
David O'Neil 18-Oct-18 4:29am    
(and I've placed a breakpoint in the Strings destructor, which isn't tripped)
CPallini 18-Oct-18 4:37am    
And 'stringsC' is a global object... OK, now I am at loss, like you.
David O'Neil 18-Oct-18 4:42am    
Technically, it is an element of the global object, but should be no difference, especially since it works as a non-library project:

namespace dwl {
class Globals {
private:
Strings stringsC;
public:
const Strings & strings() const { return stringsC; }
};
}

This writing (and the suggestions) were helpful - thanks!

By eliminating the previous sources of error, the only thing left was a binary layout issue between the library and main project file. So I went through both projects and cleaned up the #defines so all library defines were defined in the library project. I thought I had already done so, but whatever changes I made fixed the issue and the exception is now caught correctly, looking up the proper string.

Again, thanks for your time and feedback!
 
Share this answer
 
Comments
CPallini 19-Oct-18 4:23am    
Then have a 5, you deserve it.
David O'Neil 19-Oct-18 10:08am    
Thanks. It was nice to finally sleep knowing the problem was solved!
The problem is that the A-code returns some temporary data which you only store in a reference, so your app runtime isnt creating real data but having some reference to it. It is somehow like a pointer.
This code is creating a own copy of the data.
C++
const Strings strings = gDwlGlobals->strings();
const Strings strings = CString( gDwlGlobals->strings() );//plan B
If that doesnt work consider changing that interface. I made the experience that interfaces WITHOUT MFC classes working best. Like using char*
Example interface:
C++
int getString(char *buffer, int maxSize, int identifier)
 
Share this answer
 
Comments
David O'Neil 18-Oct-18 5:37am    
>> The problem is that the A-code returns some temporary data which you only store in a reference...

Unless I missed something, the A-code returns a const reference to the stringsC vector. The B-code then copies an element from that vector into a local string.
CPallini 18-Oct-18 5:47am    
I second David's remark. The method returns a reference.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900