2016-06-29 2 views
0

Ich habe den folgenden Code in C++/CLI und Beobachten hängen, während die .net-String Umwandlung * auf char StringToCoTaskMemAnsi mitStringToCoTaskMemUni oder StringToCoTaskMemAnsi-Methoden können dazu führen, dass hängen?

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; 
} 

In unserer Protokollierung kann ich „cashincdistores-- gehen zu nennen StringToCoTaskMemAnsi“ sehen und es zu ahnen, ist ein Hang nach dem Aufruf der "StringToCoTaskMemAnsi" -Methode.

Gibt es eine Möglichkeit, in der 'StringToCoTaskMemAnsi'-Marshalling-Methode hängen. Was könnte den Hang verursachen?

+0

Haben Sie das mit dem Debugger durchgegangen, oder haben Sie nur das Printf-Debugging durchgeführt? Was passiert, wenn Sie durch diese Linie gehen? –

+0

Danke David für deine Antwort. Beim Debuggen wird nicht gehangen und darüber hinaus passiert es sehr selten (1 von 50) – Sadhu

+0

Sicher, das ist möglich. Sie können die Sperre sperren, die den Heap schützt, wenn Sie etwas Unkluges tun, wie das Einfangen von SEH-Exceptions. Oder grundlegende Heap-Korruption kann dazu führen, dass der Allokator in einer Endlosschleife stecken bleibt. Fiese Probleme, keine One-Button-Fixes - es antwortet. –

Antwort

0

Warum verwenden Sie COM in erster Linie? Sie benötigen keine COM in diesem Code.

Haftungsausschluss: Sie sollten wahrscheinlich nicht ein const char * jemand anderes aus Ihrer Funktion befreien müssen zurückkehren. Das ist eine sehr einfache Möglichkeit, Speicherverluste oder mehrere freie Fehler zu erzeugen.

Ignorieren Sie den Disclaimer oben, haben Sie ein paar Möglichkeiten:

Erster Weg:

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

Der strValueAsCString Zeiger wird so lange gültig bleiben, wie context im Gültigkeitsbereich befindet.


Ein anderer Weg:

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

Hier schafft die std::string die Lebensdauer der Saite.


Siehe Overview of Marshaling als Referenz.

+0

Was ist threadsicher "StringToCoTaskMemAnsi" oder "StringToHGlobalAnsi"? – Sadhu

+0

@Sadhu diese Frage macht * keinen * Sinn. Diese beiden Funktionen dienen nicht dem gleichen Zweck, lesen Sie ihre Dokumente. Sie müssen keines von beiden verwenden. –

Verwandte Themen