【问题标题】:Expose types from embedded interop type to other assemblies将嵌入式互操作类型中的类型公开给其他程序集
【发布时间】:2014-10-28 00:16:42
【问题描述】:

我有一个 ATL COM 库,它在 MIDL 中定义了一个枚举和一个接口,例如:

[uuid(65785D49-574A-4B1B-95F1-B9C7F283364A)]
typedef enum Options
{
    Option1,
    Option2
} Options;

[
    object,
    uuid(2E3D1B1A-DF95-434F-836B-73FF1245B608),
    oleautomation,
    nonextensible,
    pointer_default(unique)
]
interface IExample : IUnknown
{
    HRESULT Test([in] Options option, [out, retval] BSTR* str);
};

然后我创建一个托管程序集并引用 TLB,TLB 创建一个 PIA 并将类型 (Embed Interop Types = true) 嵌入到托管程序集中。

在托管程序集中,我现在创建一个实现接口的类:

public class Example : IExample
{
    public string Test(Options option)
    {
        return option.ToString();
    }
}

现在我想创建第三个程序集,它引用托管程序集并创建对象并调用它,但它不允许我因为 Options 是未引用的类型(要求我包含从 typelib 生成的 PIA ):

public class Equivalence
{
    public void UseTest()
    {
        Example e = new Example();
        e.Test(Options.Option1);    // recognizes that it requires an ExampleLib.Options parameter, but that type isn't available
    }
}

使用反射器,我可以在托管程序集中看到它,但对象浏览器看不到它:

namespace ExampleLib
{
    [ComImport, CompilerGenerated, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("2E3D1B1A-DF95-434F-836B-73FF1245B608"), TypeIdentifier]
    public interface IExample

    [Guid("65785D49-574A-4B1B-95F1-B9C7F283364A"), CompilerGenerated, TypeIdentifier("15a6cf97-c415-4866-bdfb-7da65edb1faa", "ExampleLib.Options")]
    public enum Options
}

我的托管程序集本身就是一个旨在作为 API 分发的库,我想公开此枚举和接口,以便外部各方可以使用它,而不必交付从 ATL 的类型库生成的 PIA COM 库。有可能吗?

【问题讨论】:

  • 不要嵌入类型!因为您想将 ATL 库与您的 API 一起分发,所以无论如何这不是您想要的。只有在引用 TLB 的程序集中使用的类型是嵌入的,因此客户端可能会丢失某些对象。相反,您应该从 TLB 创建一个 PIA,将其部署到 GAC 并在您想要使用它的类型的每个程序集中引用它。
  • 我们根本不需要(或不希望)外部客户使用 ATL 库,他们唯一的访问权限应该是通过我们的托管 API。因此,我们需要通过此 API 公开的唯一类型是嵌入的类型。我慢慢得出结论,我需要分发 PIA 才能使其工作,但我希望它可以嵌入到程序集中以减少依赖关系。
  • 唯一可以嵌入到程序集中的是互操作类型,它不同于底层的 COM 类型! ATL 库必须部署并注册到客户端,即使您嵌入互操作类型(它们只是 COM 库的包装器)。因此,客户端能够直接访问您的非托管类型库。控制这种情况的唯一方法是生成和分发 PIA。依赖关系在这里没有争议 - 它们是您的解决方案性质的结果。您不能通过省略某些组件来减少它们。

标签: c#-4.0 interop com-interop pia type-equivalence


【解决方案1】:

这显然是做不到的。其中一个错误 (CS1748) 将我指向 this post,它表示 PIA 必须由两个程序集链接。

【讨论】:

    猜你喜欢
    • 2022-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 2023-03-04
    • 1970-01-01
    • 2012-02-27
    • 2011-10-05
    相关资源
    最近更新 更多