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
管理字符串的生命周期。
我在 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
管理字符串的生命周期。