StringToCoTaskMemUni 或 StringToCoTaskMemAnsi 方法会导致挂起?

StringToCoTaskMemUni or StringToCoTaskMemAnsi methods can cause hang?

我在 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-- going to call StringToCoTaskMemAnsi" 并怀疑在调用 'StringToCoTaskMemAnsi' 方法后出现挂起。

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

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

Disclaimer: You should probably not be returning a const char * someone else will have to free from your function. That's a very easy way to produce memory leaks or multiple free errors.

忽略上面的免责声明,您有两种可能性:

第一种方式:

#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);

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


另一种方式:

#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