2016-06-29 1 views
0

У меня есть ниже код в C++/CLI и наблюдения зависать при преобразовании строки .net обугливаться * с помощью StringToCoTaskMemAnsiСпособы StringToCoTaskMemUni или StringToCoTaskMemAnsi могут вызвать зависание?

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

Вы прошли через это с помощью отладчика, или вы только сделали отладку printf? Что происходит, когда вы проходите через эту линию? –

+0

Спасибо, Дэвид за ваш ответ. Hang не происходит во время отладки и, кроме того, происходит очень редко (1 из 50 раз) – Sadhu

+0

Конечно, это возможно. Вы можете заблокировать блокировку, которая защищает кучу, если вы сделаете что-нибудь неразумное, как ловушки исключений SEH. Или базовое повреждение кучи может заставить распределитель застрять в бесконечном цикле. Неприятные проблемы, ни одна кнопка-исправления, - отвечает он. –

ответ

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 для справки.

+0

, который является потокобезопасным «StringToCoTaskMemAnsi» или «StringToHGlobalAnsi»? – Sadhu

+0

@Sadhu это вопрос не делает * какой-либо * смысл. Эти две функции не выполняют одну и ту же цель, прочитайте их документы. Вам не обязательно использовать любой из них. –

Смежные вопросы