2012-04-04 2 views
2

У меня есть приложение C# Winforms, которое делает вызов COM-класса. При отладке с помощью Visual Studio он переходит в код C++ и возвращает S_OK, но когда функция возвращает визуальную викторину, а приложение аварийно завершает работу. Я должен завершить процесс VS-процесса, чтобы остановить запуск программы. Если я запустил приложение за пределами визуальной студии, приложение просто выйдет из строя.C# Сбой приложений при вызове метода COM Класс

Все работает нормально, и я понятия не имею, что я, возможно, сделал, чтобы вызвать эту проблему.

Любая помощь приветствуется. Благодаря

Sj

Это определение интерфейса

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

Я реферированы DLL COM и Разрешенные VS для создания Interop и использование в C# приложения:

LicenceData data = new LicenceData(); 

ILicenceReader reader = new LicenceReader(); 

reader.ReadLicenceFile(ref data, filePath); 

Спасибо за вашу помощь.

+0

Возможно, вы можете предоставить подробную информацию о вызовах COM, которые вы создаете? Кроме того, информация об ОС, архитектуре ЦП (32 бит против 64 бит), скомпилированной архитектуре процессора (AnyCPU против x86) и т. Д. Может быть полезной. – Reddog

+0

Кажется, проблема со стеклом. Не могли бы вы показать подпись вашей функции COM, как вы заявляете на C# и как вы ее называете? – Steve

+0

Настройте отладчик для остановки в SEH (Меню-> Отладка-> Исключения для VS). Запустите приложение с приложенным отладчиком, но не используйте пошаговое выполнение. Посмотрите, какое сообщение будет отправлено –

ответ

0

Готов поспорить, что подсистема COM пытается развязать BSTR, выделенную в стеке, или, возможно, выделен интеллектуальным указателем на стек.

BSTR должны быть выделены SysAllocString. Результат этого может быть возвращен как есть, так как он не находится в стеке, и ничто не попытается освободить его ошибочно.

Если вы используете класс BSTR с интеллектуальным указателем, такой как CComBSTR или _bstr_t, вам необходимо установить элемент IssuedBy через Detach. CComBSTR :: Detach() вернет указатель на BSTR и не попытается освободить его, если локальный экземпляр CComBSTR выходит из области видимости.

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

Другая возможность заключается в том, что вы пытаетесь сделать что-то вроде plicenceData = новые plicenceData в вашем COM класса, перезапись экземпляр передается в. Это не будет работать.

В конце концов, в значительной степени единственная причина, по которой COM-функция выходит из строя после ее завершения и возвращается из-за проблем с сортировкой. Это слой между вашим кодом C# и вызываемым C++, который пытается перевести данные через квартиру и, возможно, границы процесса. Вам необходимо убедиться, что вы следуете правилам COM в письме, чтобы разрешить сортировку выполнять свою работу.

Итак, дважды проверьте все указатели. Они находятся в стеке или в куче? Они должны быть в куче. Соответствуют ли все BSTR? Использование умных классов BSTR обычно поможет значительно, но просто помните, что вы не можете вернуть сырые элементы. Используйте эти классы, поскольку они должны использоваться.

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