C#应用程序在对COM类的方法调用时崩溃

时间:2012-04-04 22:39:39

标签: c# c++ com

我有一个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);

感谢您的帮助。

1 个答案:

答案 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类通常会有很大帮助,但请记住,您无法返回原始成员。使用这些类,因为它们应该被使用。