I'm calling C++ COM interface from C# code using a dll. At the C++ side, i have a WCHAR* global variable which is updated through a method with a BSTR parameter.
The problem is that, when i first call the C++ wrapper method from C# to change the variable, everything works fine, but at the moment that i call another C++ wrapper method from C#, unexplainably the WCHAR* global variable points to a different memory position and its value gets corrupted.
Some code:
//THE C# side:
capture.filename = PATH + "\\" + DIRECTORY_NAME + "\\";
capture.MaxMinutesPerFile = MAX_MINUTE_PER_FILE;
"capture" is an object of the C++ wrapper class (i think it is autogenerated when building the C++ code to a DLL. Not my code). "filename" property calls a "put_FileName" C++ method and "MaxMinutesPerFile" a "put_MaxMinutesPerFile" method.
//C++ code
WCHAR *m_bstFileName = L"None";
(...)
STDMETHODIMP CCaptureMF::put_FileName(BSTR PathName)
{
EnterCriticalSection(&m_critsec);
HRESULT hr = S_OK;
m_bstFileName = PathName;
LeaveCriticalSection(&m_critsec);
return hr;
}
STDMETHODIMP CCaptureMF::put_MaxMinutesPerFile(LONG Minutes)
{
MaxMinutes= Minutes;
return S_OK;
}
So, after calling "put_FileName", "m_bstFileName" is updated correctly with the "PathName" value, but just after calling "MaxMinutesPerFile" (or any other interface wrapper method), "m_bstFileName" gets corrupted pointing to a different memory position and fulfilled with strange data.
Thank you.
EDIT:
To make a buffer of "m_bstFileName" and then copy the "PathName" data, i used the following code, taking in mind that "m_bstFileName" size can change at runtime:
m_bstFileName = (wchar_t*)malloc(sizeof(PathName));
wcscpy(m_bstFileName, PathName);
That code works fine, but the rest of the program behaves bad. I´m not sure why, i should investigate more, but for now, could you analyze that pice of code and tell me if it is correct or if i should implement it in other way?
SOLUTION:
Ok, following your recomendations i have finally implemented the following code, which works perfect for the whole application:
CComBSTR m_bstFileName = L"None";
(...)
STDMETHODIMP CCaptureMF::put_FileName(BSTR PathName)
{
EnterCriticalSection(&m_critsec);
HRESULT hr = S_OK;
m_bstFileName = PathName;
if (g_pCapture)
{
g_pCapture->SetPath(m_bstFileName);
}
LeaveCriticalSection(&m_critsec);
return hr;
}
If you think that this can be implemented better, just tell.
Thank you for your help!
You need to copy the string to m_bstFileName, not just assign it. Use something like