【发布时间】:2014-11-27 16:11:52
【问题描述】:
我正在使用 dll 从 C# 代码调用 C++ COM 接口。 在 C++ 端,我有一个 WCHAR* 全局变量,它通过带有 BSTR 参数的方法进行更新。
问题是,当我第一次从 C# 调用 C++ 包装器方法来更改变量时,一切正常,但是当我从 C# 调用另一个 C++ 包装器方法时,无法解释的 WCHAR* 全局变量指向一个不同的内存位置,其值被破坏。
一些代码:
//THE C# side:
capture.filename = PATH + "\\" + DIRECTORY_NAME + "\\";
capture.MaxMinutesPerFile = MAX_MINUTE_PER_FILE;
“capture”是 C++ 包装类的一个对象(我认为它是在将 C++ 代码构建到 DLL 时自动生成的。不是我的代码)。 “filename”属性调用“put_FileName”C++ 方法,“MaxMinutesPerFile”调用“put_MaxMinutesPerFile”方法。
//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;
}
因此,在调用“put_FileName”之后,“m_bstFileName”会使用“PathName”值正确更新,但在调用“MaxMinutesPerFile”(或任何其他接口包装方法)之后,“m_bstFileName”会损坏,指向不同的内存位置并满足了奇怪的数据。
谢谢。
编辑:
为了制作“m_bstFileName”的缓冲区,然后复制“PathName”数据,我使用了以下代码,考虑到“m_bstFileName”的大小可以在运行时改变:
m_bstFileName = (wchar_t*)malloc(sizeof(PathName));
wcscpy(m_bstFileName, PathName);
该代码运行良好,但程序的其余部分表现不佳。我不知道为什么,我应该进行更多调查,但是现在,您能否分析一下这段代码并告诉我它是否正确,或者我是否应该以其他方式实现它?
解决方案:
好的,根据您的建议,我终于实现了以下代码,非常适合整个应用程序:
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;
}
如果您认为这可以更好地实现,请告诉。
感谢您的帮助!
【问题讨论】:
-
调用完成后调用者会销毁BSTR。您必须对字符串进行深度复制才能保留它。
-
将 m_bstFileName 声明为 CComBSTR,然后分配将复制传递给它的 BSTR。
-
请记住,sizeof 不适用于指针。 @CyberSpock 已经给出了正确的答案,但如果你要手动操作,你应该
calloc (wcslen(PathName)+1, sizeof *m_bstFileName).
标签: c# c++ com corruption