Visual C++ Release build - is string getting corrupted when passed across DLL because compiled with different runtime version?

StackOverflow https://stackoverflow.com/questions/18021517

  •  21-06-2022
  •  | 
  •  

質問

After building in Release mode, I am seeing exceptions which didn't occur in Debug mode. When debugging the release build, it looks like string references are not being passed correctly from the EXE (our application) to the DLL which is receiving the string reference.

Our EXE code looks like this:

string contents = "handle_message(): received=" + msg->encode();
LOG4CXX_DEBUG(logger, contents);

The LOG4CXX_DEBUG is going to log4cxx.dll, whose code looks like this:

CharMessageBuffer& CharMessageBuffer::operator<<(const std::basic_string<char>& msg) {
   if (stream == 0) {
      buf.append(msg);
   } else {
      *stream << msg;
   }
   return *this;
}

Looking at the Call Stack in the debugger, when I navigate down to the frame which has our source, I can see that contents is a valid string with size=583, capacity=838.

In the frame inside the log4cxx.dll (the next frame above in the stack) the string reference shows size=838, capacity=363113231 (and the values are all garbage).

Both our app and log4cxx.dll were compiled on the same machine, using the same runtime settings (/MD), but different versions of Visual Studio. The log4cxx dll was compiled using Visual Studio 2008 and our application was compiled using Visual Studio 2010. Running dumpbin on the 2 objects shows:

Our App (EXE)

MSVCP100.dll
MSVCR100.dll

log4cxx.dll (DLL)

MSVCP90.dll
MSVCR90.dll

Is this problem due to the fact that they are using different runtime versions?

役に立ちましたか?

解決

If you pass non-POD (plain old datatypes) between DLL/EXE boundaries (like STL string or CRT FILE pointers) you must use the same shared CRT.

In your case, you must recompile all DLLs/LIBs with the same compiler!

See also: I can pass std::string for a Dll and what i can do with DLL´s?

他のヒント

The implicit question is:"Is there a way to pass data, hopefully using string and other STL containers, to DLLs of another version of visual studio either previous or later than the one that I'm using?".

Aside from using POD, there are probably three approaches: shared memory, sockets( to local host ) and MSMQ. All of these methods require additional extensive programming, but the deeper answer is found in how the interface is changing the input parameter.

I have found a possible solution to the string passing problem on the internet. It removes one layer of corruption; cast a pointer to the container to a uint and pass the uint. Dereference the uint to the pointer and the object is revealed. Beware, auto_ptrs are usually deleted in this process, so don't use them. If the passed object is still offset incorrectly( this happened to me with VS08 passing to a VS13 ), then pass the c_str() of the string instead. It's certainly inelegant, but we need to know all the alternatives. See "HowTo: Export C++ classes from a DLL" in Code Project( Nov 22, 2012 ).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top