我在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'编组方法是否有可能挂起。什么可能导致挂起?
答案 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以供参考。