创建仅包含枚举的 COM 库时出现问题

2024-05-10

我正在做一个 COM 互操作项目。用 C# 和 .NET Interop 替代一些 VB 和 C++ ATL COM 项目。当我在 .NET 中定义枚举并将它们设为 ComVisible 时,它​​们会公开为 Typelib.EnumType_EnumValue 而不仅仅是 Typelib.EnumValue。 typelib 导出器这样做是为了确保值名称是唯一的。但我知道我的所有枚举都是唯一的,所以我不需要下划线。如果我不去掉下划线,还有很多客户端代码需要更改。

为了找到这个问题的解决方案,我在 IDL 文件中定义了枚举,并从中创建了一个 typelib 和 .Net 互操作。

[
  uuid(64893FD4-359D-46B9-BC1E-48C055796104),
  version(1.0),
  helpstring("ABC"),
  helpfile("AAA.chm"),
  helpcontext(0x00000001)
]

library EnumTypeLib
{
    importlib("stdole2.tlb");
    typedef [uuid(8FF85069-C4E2-4540-A277-4C0F3C19B807), helpstring("MyEnum"), helpcontext(0x00000066)]
    enum MyEnum {
        Value1 = 0,
        Value2 = 1,
    } MyEnum;
};

我使用 MIDL.exe 创建一个类型库,它生成一个 tlb 文件。

我用 tlbimp.exe 创建一个程序集。使用与其他 Interop 程序集相同的密钥对该程序集进行签名。

tlbimp OpenStructureAdapterEnum.tlb /keyfile:KeyFile.snk

然后我用 regasm.exe 注册程序集 该程序集看起来不错,并且包含没有下划线的枚举。但问题是无法从 OLE/COM 对象查看器或 VBA 或 VB6 看到 COM 库。当我从另一个 COM 公开的程序集引用枚举时,包含对枚举的引用的接口部分将作为受限制的方法公开。

[restricted] void Missing7();
[restricted] void Missing8();
[restricted] void Missing9();
[restricted] void Missing10();

如何创建仅包含枚举(无下划线)的 COM 库并从其他 .net Interop 程序集中引用它们?


首先回答你的最后一个问题。您想要的是 TypeLib 而不是 COM 库。 COM 接口是一堆代码和函数指针,而 TypeLib 是与这些指针交互的映射(以及定义和枚举以及一堆其他东西)。只有当它们结合在一起时,才有 COM 库。由于没有 COM 接口,因此无法拥有 COM 库。

微软提供了一个例子来说明如何创建一个没有接口的 TypeLib http://support.microsoft.com/kb/143258。它与您所描述的非常相似。您会注意到,其中没有 COM 接口;正因为如此,它必须保持一个低级的 TypeLib。

下一个问题是.NET 程序集。当你使用TlbImp.exe http://msdn.microsoft.com/en-us/library/tt0cf3sx%28v=vs.71%29.aspx将枚举导入到您的代码中,这允许您在代码中(在程序集中)使用这些枚举。这是您可以使用枚举执行的操作的限制。您无法导出这些枚举,因为它们不属于您的 .NET 代码。该枚举由 TypeLib 所有。您的 .NET 代码有权使用该枚举,但它不能声明拥有该枚举。

最后,回答你的第一个问题。您需要使用.NET 提供的功能。它能够定义枚举并导出它们并使它们在 COM 中可见。虽然我理解命名约定带来的挫败感,但这不是您应该尝试解决或绕过的问题。正如您所看到的,尝试绕过命名约定的这个小问题已经导致了严重的问题,实际上使您的新代码无法使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建仅包含枚举的 COM 库时出现问题 的相关文章

  • 当操作系统显示语言为非英语时获取本地时区标识符

    奇怪的是 TimeZone CurrentTimeZone StandardName根据计算机显示语言返回本地化名称 我想要一个可以提供给的程序化标识符TimeZoneInfo在下面的代码中 TimeZoneInfo timeZoneInf
  • WPF:Prism 对于小型应用程序来说是不是太过分了?

    如果我不将我的应用程序分成不同的模块 否则我会认为 Prism 确实是可行的方法 我应该使用 Prism 吗 我知道 Prism 提供了一个方便的实现ICommand 我可以自己在一页代码中完成 并为我们提供IEventAggregator
  • Windows 7 任务栏:捕获缩略图

    是否可以从 Win7 任务栏捕获 实时 缩略图 我想在我的应用程序中显示 另一个窗口的 预览 但如何使用 NET 提取这些预览 Yes MSDN 杂志解释了如何 http msdn microsoft com en us magazine
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • IEnumerable 与 IReadOnlyList

    选择有什么区别IEnumerable
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 如何动态创建 Dapper 查询的参数

    我有一个值字典 例如 Name Alex 有没有办法将其作为查询参数传递给 Dapper 这是一个显示我想要做什么的示例 IDictionary
  • 从 .NET 设置系统时区

    有没有人有一些代码可以从 NET 获取 TimeZoneInfo 字段并执行互操作代码以通过 SetTimeZoneInformation 设置系统时区 我意识到它基本上是将 TimeZoneInfo 成员映射到结构成员 但对我来说 这些字
  • MSBuild 编译解决方案时找不到 SGen

    我在这里查看了其他几个与 SGen 相关的问题 要么他们的答案不适用 要么他们的答案不能为我解决这个问题 我安装了几个 SDK 来解决这个问题 但没有成功 不应更改引用类型 因为这是唯一出现问题的地方 一次建议是将 SGen exe 放入C
  • 在nodejs中解密.Net cookie

    我在 Net 中创建了一个加密的cookie 并尝试在nodejs 中解密它的内容 但是nodejs不断抛出异常 TypeError DecipherFinal失败 在 Net中 我使用带有密钥的AES加密方法 932D86BB1448EE
  • JavaFX 脚本和 Java

    简单的问题 我可以在桌面应用程序中混合 Java 和 JavaFX Script 代码吗 如果可能的话 您能给我提供一些示例链接吗 或者我可以将定制的 javafx CustomNode s 打包在 jar 中 并在我的项目中与标准 SWI
  • 如何在 C# 中将字符串的内容复制到剪贴板? [复制]

    这个问题在这里已经有答案了 如果字符串中有一些文本 如何将其复制到剪贴板 以便用户可以将其粘贴到另一个窗口 例如 从我的应用程序粘贴到记事本 您可以使用System Windows Forms Clipboard SetText
  • 从调试版本检测发布版本的最佳方法? 。网

    所以我有大约 10 个简短的 css 文件与 mvc 应用程序一起使用 有像 错误 css 登录 css ETC 只是一些非常短的 css 文件 使更新和编辑变得容易 至少对我来说 我想要的是能够优化 if else 分支而不是将其合并到最
  • 以编程方式获取命名管道的系统名称

    我正在使用 WCF NetNamedPipeBinding 编写进程间通信 我的目标是让服务在 net pipe localhost service 上运行 所以我运行最简单的主机 host new ServiceHost contract
  • .NET - MVC 应用程序外部的 Razor - 删除 @inherits 和提供 @model 时出现问题

    抱歉问了这么长的问题 我把它分成了三个问题 可以分别阅读 如果你能帮我解决一个问题 请帮我 我有一个 Razor 引擎的自定义实现 所有作品和模板均已编译并可以使用 手头有一些实现涉及具有通用的基类Model允许强类型视图 模板 的属性 此
  • 如何使用c#/VB.NET在word中插入书签

    我正在尝试使用 C 在 Word 文档中添加书签 但它不起作用 而且我在 msdn 文档和互联网上都找不到任何帮助 这就是我正在尝试做的事情 我正在阅读 Word 文档 然后在该文档中搜索关键字 然后将该文本转换为超链接 效果很好 现在 我
  • 如果将其名称作为参数传递,如何在方法中打开表单

    我正在尝试创建一个标准方法来根据传递给它的参数打开表单 基本上 要完成此任务 using Quotes newQte new Quotes newQte ShowDialog 通过替换 Quotes with a passed parame
  • 如何防止打印屏幕

    我有一个要求 我正在开发的应用程序阻止用户轻松捕获屏幕内容 我已经表示 没有可行的方法可以完全防止这种情况发生 但我正在寻找方法来为这一过程引入一些障碍 我正在使用 C NET 2 0 和 WinForms 你不能 您能做的最好的事情就是在
  • List 与 IEnumerable 的协变和逆变

    所以 假设我有 Public Interface ISomeInterface End Interface Public Class SomeClass Implements ISomeInterface End Class 如果我有MyL

随机推荐