【问题标题】:C# COM visible .Net assembly with struct from legacy C++ COM DLLC# COM 可见 .Net 程序集,带有来自旧版 C++ COM DLL 的结构
【发布时间】:2012-06-30 04:33:19
【问题描述】:

我们有一个传统的 C++ COM DLL,它在 IDL 中定义了一个结构。
IDL 的简化版本包含:

typedef struct 
{
    int num;
} LegacyStruct;

interface ILegacyInterface : IUnknown
{
    HRESULT GetStruct( [in,out] LegacyStruct* pVal );
}

我们现在需要定义一个实现ILegacyInterface 的.Net C# COM 可见程序集。

在 C# 项目中,我们添加对旧版 COM DLL 的引用并定义一个实现此接口的类:

[ComVisible( true )]
public class CSClass : ILegacyInterface
{
    public void GetStruct( ref LegacyStruct pVal )
    {
        ....
    }
}

我们的目标是在 C++ COM 客户端程序中使用这个暴露于 COM 的 C# 程序集类。该程序应该能够使用旧版 COM DLL 和实现 ILegacyInterface 的新 C# 程序集类。

编译时显示以下警告:
类型库导出器警告处理'CSClass.GetStruct(pVal)'。警告:非 COM 可见值类型“LegacyStruct”被当前导出的类型或其基类型之一引用。

由于 LegacyStruct 对 COM 不可见,因此生成的程序集的 .tlb 没有公开 GetStruct() 方法(即,当使用 oleview 查看时)。
显然 C++ COM 客户端无法编译:
error C2039: 'GetStruct' : is not a member of 'CSClass'

有没有办法确保在旧版 C++ COM DLL 中定义的 LegacyStruct 在用于 C# COM 可见 .Net 程序集的方法时正确公开?

【问题讨论】:

  • 你真的应该使用 C++/CLI 包装类来与 COM 通信。
  • 您能发布该结构的非简化 IDL 吗?
  • 结构的非简化版本也很简单... typedef struct { long days;长毫秒;长区; } LegacyStruct;
  • 该结构没有与之关联的 uuid,但我尝试了使用和不使用 uuid。结果是一样的,可惜……
  • 请发布 LegacyStruct 的 C# 声明

标签: .net com interop com-interop


【解决方案1】:

要解决此问题,需要以下 2 项:

  1. 旧版 COM IDL 必须包含正在定义的结构的 uuid。 tcarvin 在上面提到了这一点。除了 uuid 之外,结构标记名称 必须 与结构名称相同。将标签留在外面是不够的,即,即使 uuid 存在。这是新的结构定义:

    typedef [uuid(XXX-YYY-ZZZ-AAA-BBB)]
    结构 LegacyStruct
    {
    整数;
    } LegacyStruct;

    没有与结构关联的 uuid 将在生成的 .Net 程序集中包含其定义的副本以及自动生成的 uuid。就同​​名的 COM 而言,这显然是一个完全不同的结构。

  2. 将旧版 COM DLL 添加为对 C# 项目的引用时,将“嵌入互操作类型”属性设置为 False 很重要。这也将确保遗留 COM DLL 的定义(例如结构等)不包含在生成的 .Net 程序集中。

【讨论】:

    【解决方案2】:

    我意识到这并没有严格回答您关于为什么会发生这种情况的问题,但是我遇到了与 tlbimp 类似的问题,并且我学会了避免它。

    我通常发现 .Net 项目自动导入 TLB 的方式过于严格。解决此问题的一种方法是使用所有适当的 ComInterface、Guid 和 CoClass 属性在 C# 文件中重新声明 IDL 内容。

    tlbimp+reflector 也是为这些声明生成骨架的好方法。如果您查看 tlbimp 的反编译结果,您可以看到您期望在 .Net 声明中缺少哪些属性,这可能有助于您弄清楚发生了什么。

    【讨论】:

      猜你喜欢
      • 2018-08-14
      • 2011-05-02
      • 1970-01-01
      • 2011-07-27
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多