【问题标题】:Variable corrupted when calling C++ COM from C#从 C# 调用 C++ COM 时变量损坏
【发布时间】: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 不适用于指针。 @Cyber​​Spock 已经给出了正确的答案,但如果你要手动操作,你应该 calloc (wcslen(PathName)+1, sizeof *m_bstFileName).

标签: c# c++ com corruption


【解决方案1】:

在最基本的情况下,您需要创建一个缓冲区来将字符串复制到其中。根据您使用的框架,可以通过 cstring、ccombstr、std::string 等赋值来完成相同的操作。

【讨论】:

  • 忘记了缓冲区。我的 C++ 有点生疏了。
  • 比你。您能否以正确的方式在“m_bstFileName”处创建缓冲区的示例?它不是固定大小,因为此变量可以在运行时通过代码更改。再次感谢。
【解决方案2】:

您需要将字符串复制到 m_bstFileName,而不仅仅是分配它。使用类似

strcpy(m_bstFileName, 路径名);

【讨论】:

  • 在目标字符串中分配了足够的空间之后。
  • 不要忘记分配(在堆栈或堆上)某个地方以将 PayhName 复制到。
猜你喜欢
  • 2013-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-08
  • 1970-01-01
相关资源
最近更新 更多