我有一个C#Winforms应用程序,它调用COM类。使用Visual Studio进行调试时,它会进入c ++代码并返回S_OK,但是当函数返回visual studio挂起并且应用程序崩溃时。我必须在VS进程上结束进程以阻止程序运行。如果我在visual studio之外运行应用程序,应用程序就会崩溃。
一切都很好,我不知道我为解决这个问题做了什么。
感谢任何帮助。感谢
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;
};
我引用了COM dll并允许VS生成Interop以及c#应用程序中的用法:
LicenceData data = new LicenceData();
ILicenceReader reader = new LicenceReader();
reader.ReadLicenceFile(ref data, filePath);
感谢您的帮助。
答案 0 :(得分:0)
我敢打赌,COM子系统正在尝试解组在堆栈上分配的BSTR,或者可能在堆栈上分配了智能指针。
必须使用SysAllocString分配BSTR。这样的结果可以按原样返回,因为它不在堆栈中,没有任何东西会试图错误地释放它。
如果你使用智能指针BSTR类,如CComBSTR或_bstr_t,那么你需要通过Detach设置IssuedBy成员。 CComBSTR :: Detach()将返回指向BSTR的指针,当CComBSTR的本地实例超出范围时,不会尝试释放它。
plicenceData->IssuedBy = CComBSTR("Some Dude").Detach();
另一种可能性是你尝试在你的COM类中执行类似plicenceData = new plicenceData的操作,覆盖传入的实例。这不起作用。
最后,COM函数在完成并返回后失败的唯一原因是由于编组问题。它是您的C#代码和被调用的C ++之间的层,它试图跨公寓转换数据,并可能处理边界。您需要确保遵循COM规则,以允许编组执行它的工作。
所以,请仔细检查所有指针。它们在堆栈上还是在堆上?他们需要在堆上。是否所有BSTR都分配得恰当?使用智能BSTR类通常会有很大帮助,但请记住,您无法返回原始成员。使用这些类,因为它们应该被使用。