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

Posted

技术标签:

【中文标题】C# 应用程序在对 COM 类的方法调用时崩溃【英文标题】:C# Application crashes on method call to COM Class 【发布时间】:2012-04-04 22:39:39 【问题描述】:

我有一个调用 COM 类的 C# Winforms 应用程序。使用 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);

感谢您的帮助。

【问题讨论】:

也许您可以提供有关您正在进行的 COM 调用的详细信息?此外,有关操作系统、CPU 架构(32 位与 64 位)、已编译 CPU 架构(AnyCPU 与 x86)等的信息都会有所帮助。 堆栈似乎有问题。您能否展示一下您的 COM 函数的签名、您如何在 C# 中声明以及如何调用它? 将调试器配置为在 SEH 上停止(菜单->调试->VS 异常)。在附加调试器的情况下运行应用程序,但不要使用逐步执行。查看将报告什么异常 我打开了所有异常,它仍然只是杀死了视觉工作室。它在 64 位 Windows 7 机器上运行。在 c# 应用程序和 COM dll 中,目标平台都是 x86。函数调用通过 ref 传回一个带有一些字符串和 int 的结构。 @Sjblack,向我们展示 IDL 文件以及操作中涉及的所有接口和类的对应 C# 定义 【参考方案1】:

我敢打赌,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 类通常会有很大帮助,但请记住,您不能返回原始成员。按照预期使用这些类。

【讨论】:

以上是关于C# 应用程序在对 COM 类的方法调用时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何在对引发异常的 C# webmethod 的 ajax 调用上指定消息?

c# 有调用一个类的静态方法,是不是执行这个类的构造函数

如何在C#中,在一个类里调用另外一个类的方法

C#中通过委托来调用对象方法的基本过程

c#如何创建类 调用

C# virtual 和 abstract 区别