StringToCoTaskMemUni或StringToCoTaskMemAnsi方法会导致挂起吗?

时间:2016-06-29 14:16:41

标签: c++-cli hang mixed-mode

我在c ++ / CLI中有以下代码,并在使用StringToCoTaskMemAnsi将.net字符串转换为char *时观察到挂起

const char* CDICashInStringStore::CDIGetStringVal( void )
{
    unsigned int identifier = (unsigned int)_id;
    debug(" cashincdistores--routing call to .Net for CDI String %d", identifier);
    NCR::APTRA::INDCDataAccess::IStringValue^ stringValueProvider = (NCR::APTRA::INDCDataAccess::IStringValue^)GetStringProvider()->GetProvider();
    String^ strValue = stringValueProvider->GetStringValue(identifier);
    debug(" cashincdistores-- going to call StringToCoTaskMemAnsi);
    IntPtr iPtr = Marshal::StringToCoTaskMemAnsi(strValue);
    debug(" cashincdistores-- StringToCoTaskMemAnsi called);
    // use a local (retVal is not needed)
    const char * ansiStr = strdup((const char *) iPtr.ToPointer());
    Marshal::FreeCoTaskMem(iPtr);


    debug(" cashincdistores--got results %d %s",identifier,ansiStr);
    // The returned memory will be free() 'ed by the user
    return ansiStr;
}

在我们的日志记录中,我可以看到“cashincdistores--将调用StringToCoTaskMemAnsi”并怀疑在调用'StringToCoTaskMemAnsi'方法后有一个挂起。

'StringToCoTaskMemAnsi'编组方法是否有可能挂起。什么可能导致挂起?

1 个答案:

答案 0 :(得分:0)

为什么你首先使用COM?您不需要该代码中的任何COM。

  

免责声明:您应该返回const char *其他人将不得不从您的功能中解脱出来。这是产生内存泄漏或多个免费错误的一种非常简单的方法。

忽略上述免责声明,您有几种可能性:

第一种方式:

#include <msclr/marshal.h>
msclr::interop::marshal_context context;
const char* strValueAsCString = context.marshal_as<const char*>(strValue);

// Probably bad
const char* ansiStr = strdup(strValueAsCString);

只要strValueAsCString在范围内,context指针就会保持有效。

另一种方式:

#include <string>
#include <msclr/marshal_cppstd.h>
std::string strValueAsStdString = msclr::interop::marshal_as<std::string>(strValue);

// Probably bad
const char* ansiStr = strdup(strValueAsStdString.c_str());

此处,std::string管理字符串的生命周期。

请参阅Overview of Marshaling以供参考。