2012-04-04 6 views
2

Ich habe eine C# Winforms-Anwendung, die einen Aufruf an eine COM-Klasse aufruft. Beim Debuggen mit Visual Studio wird in den C++ - Code verzweigt und S_OK zurückgegeben, aber wenn die Funktion zurückkehrt, bleibt Visual Studio hängen und die Anwendung stürzt ab. Ich muss Prozess auf dem VS-Prozess beenden, um das Programm zu beenden zu beenden. Wenn ich die App außerhalb von Visual Studio starte, stürzt die Anwendung einfach ab.C# -Anwendung stürzt bei Methodenaufruf zu COM ab Klasse

Alles funktionierte gut und ich habe keine Ahnung, was ich getan haben könnte, um dieses Problem zu verursachen.

Jede Hilfe wird geschätzt. Dank

Sj

Dies ist die Schnittstellendefinition

typedef struct 
{ 
    long ExpiryData 
    BSTR IssuedBy; 
} LicenceData; 

[ 
    object, 
    uuid (5A734F95-EABE-440B-8B7E-0F73538A24AC), 
    pointer_default(unique), 
    helpstring("ILicenceReader Interface"), 
] 
interface ILicenceReader : IDispatch 
{ 
    HRESULT ReadLicenceFile ([in, out]LicenceData* plicenceData, LPCTSTR filePath); 
}; 

[ 
    uuid(C2833A21-6586-4648-ABC8-D42BC3225699)  
] 
coclass LicenceReader 
{ 
    [default] interface ILicenceReader; 
}; 

ich die COM-DLL verwiesen haben und erlaubt VS die Interop und die Verwendung in der C# Anwendung zu generieren:

LicenceData data = new LicenceData(); 

ILicenceReader reader = new LicenceReader(); 

reader.ReadLicenceFile(ref data, filePath); 

Danke für Ihre Hilfe.

+0

Vielleicht könnten Sie Details zu den COM-Anrufen bereitstellen, die Sie vornehmen? Darüber hinaus könnten Informationen über Betriebssystem, CPU-Architektur (32 Bit vs. 64 Bit), kompilierte CPU-Architektur (AnyCPU vs. x86) usw. hilfreich sein. – Reddog

+0

Scheint ein Problem mit dem Stapel. Können Sie die Signatur Ihrer COM-Funktion anzeigen, wie deklarieren Sie in C# und wie nennen Sie es? – Steve

+0

Konfigurieren Sie den Debugger auf SEH zu stoppen (Menü-> Debug-> Ausnahmen für VS). Führen Sie die Anwendung mit dem angehängten Debugger aus, aber führen Sie keine schrittweise Ausführung aus. Sehen Sie, welche Ausnahme gemeldet wird –

Antwort

0

Ich wette, dass das COM-Subsystem versucht, einen BSTR zu entpacken, der auf dem Stapel zugeordnet ist, oder vielleicht mit einem intelligenten Zeiger auf dem Stapel zugewiesen wurde.

BSTRs müssen mit SysAllocString zugewiesen werden. Das Ergebnis davon kann zurückgegeben werden, wie es ist, da es nicht auf dem Stapel ist und nichts wird versuchen, es fälschlicherweise zu befreien.

Wenn Sie eine Smart-Pointer-BSTR-Klasse wie CComBSTR oder _bstr_t verwenden, müssen Sie das IssuedBy-Member über ein Detach festlegen. CComBSTR :: Detach() wird den Zeiger auf den BSTR zurückgeben und nicht versuchen, es freizugeben, wenn diese lokale Instanz von CComBSTR den Geltungsbereich verlässt.

plicenceData->IssuedBy = CComBSTR("Some Dude").Detach(); 

Eine andere Möglichkeit ist, dass Sie versuchen, so etwas wie plicenceData = new plicenceData in Ihrer COM-Klasse zu tun, in die Instanz überschreiben übergeben. Das wird nicht funktionieren.

Am Ende ist der einzige Grund, warum eine COM-Funktion fehlschlägt, nachdem sie beendet und zurückgegeben wurde, aufgrund von Marshalling-Problemen. Es ist die Ebene zwischen Ihrem C# -Code und dem aufgerufenen C++, die versucht, die Daten über die Wohnung und möglicherweise Prozessgrenzen zu übersetzen. Sie müssen sicherstellen, dass Sie die COM-Regeln beachten, damit das Marshalling seine Aufgabe erfüllen kann.

Also, überprüfen Sie alle Ihre Zeiger. Sind sie auf dem Stapel oder auf dem Haufen? Sie müssen auf dem Haufen sein. Sind alle BSTRs richtig zugeordnet? Die Verwendung von intelligenten BSTR-Klassen hilft normalerweise erheblich, aber denken Sie daran, dass Sie die rohen Elemente nicht zurückgeben können. Verwenden Sie diese Klassen wie erwartet.

Verwandte Themen