如何通过互操作公开 COM 库中定义的枚举作为 C# 函数的返回类型

2024-01-02

希望问题很清楚,但为了清楚起见,请补充一下:

我有一个 VB6 dll,它定义了我在 C# dll 中引用的枚举。 C# dll 使用 idispatch 接口以正确的方式定义 CCW,该接口声明返回类型为枚举的函数。

运行 regasm 时,我收到一条警告,指出枚举在 COM 中不可见,因此该函数未导出。因为它是在我的 VB6 库中定义的,所以我认为它已经是 COM 可见的,因为它是在 COM dll 中定义的。

我意识到我可以停止乱搞并使用 int 来传递枚举,然后只对任一端进行转换,但这确实令人沮丧,我想知道是否存在一种方法。

根据要求,这里是一些示例代码:

VB6 dll 定义枚举

Public Enum myEnum
    first = 0
    second = 1
End Enum

这通过互操作导入到 C# 中,如果您查看元数据,它看起来像这样

[Guid("EnumGUID")]
public enum myEnum
{
    first = 0,
    second = 1        
}

然后定义CCW接口

[ComVisible(true)]
[Guid("InterfaceGuid")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IMyCCWInterface
{
    [DispId(1)]
    myEnum myFunction();
}

Regasm 抱怨 myEnum 不可见。我必须同意它,因为元数据视图没有 com 可见属性。奇怪的是,如果我使用 VB dll 中定义的其他类型作为函数的参数,我不会收到任何抱怨,它只是看起来是枚举,我猜这是因为我实际上公开了 VB6 枚举的互操作实现,而不是实际枚举。

所以我想我理解这个问题,我想知道是否有一种方法可以使用枚举来完成此工作,而不涉及破解任何中间或自动生成的代码。


看来解决方案是将 C# 项目中导入的 COM 程序集的“Embed Interop Types”属性设置为 False。

为了测试这一点,我创建了一个 VB COM dll 作为StackOverflow.ExampleCom里面有以下代码

Public Enum EThing
    eThingOne = 1
    eThingTwo = 2
End Enum
Private mThing As EThing
Private Sub Class_Initialize()
    mThing = eThingOne
End Sub
Public Property Let Thing(newVal As EThing)
    mThing = newVal
End Property
Public Property Get Thing() As EThing
    Thing = mThing
End Property

然后我创建了一个 C# 类项目并导入了这个 StackOverflow COM 库。然后,以下 C# 代码创建一个 COM 对象,该对象重新公开 VB 代码中定义的枚举类型,创建与 OP 描述的相同情况。

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using StackOverflow;

namespace EnumDemo
{
    [ComVisible(true)]
    [Guid("c30d35fe-2c7f-448b-98be-bd9be567ce70")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IEnumDemo
    {
        [DispId(1)]
        EThing Thing
        {
            get;set;
        }
    }

    [ComVisible(true)]
    [Guid("af328c82-08e3-403e-a248-8c46e27b48f3")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("StackOverflow.EnumDemo")]
    public class EnumDemo
    {
        private EThing mThing = EThing.eThingOne;
        public EThing Thing { get { return mThing; } set { mThing = value; } }
    }
}

如果我们构建这个,然后尝试使用此程序集创建一个类型库regasm /tlb:EnumDemo.tlb bin\Debug\EnumDemo.dll然后我收到有关使用非 COM 可见值类型的警告。然而,一旦对 VB COM dll 的引用将“嵌入互操作类型”设置为 false,警告就会消失,并且使用 OleView 检查生成的类型库会显示该类型正在被使用,并且importlib已添加以引用原始 dll。

library EnumDemo
{
    // TLib :     // TLib :  : {D482D5CB-EE6C-455A-A28A-D26A5AC579D5}
    importlib("StackOverflow.dll");
    // TLib : mscorlib.dll : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
    ...
    interface IEnumDemo : IDispatch {
        [id(0x00000001), propget]
        HRESULT Thing([out, retval] EThing* pRetVal);
        [id(0x00000001), propput]
        HRESULT Thing([in] EThing pRetVal);
    };
    ...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何通过互操作公开 COM 库中定义的枚举作为 C# 函数的返回类型 的相关文章

  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

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

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • 如何将具有固定值的路径缩放为动态可组合大小?

    我有一个简单的Box我想将其剪辑为自定义形状的可组合项 但每当我尝试它时 形状的尺寸仍然非常僵硬且很小 我尝试使用在路径级别上进行缩放Matrix 但无济于事 这是示例 const val clockHand M0 80 52L2 86l2
  • Flex 4 Spark 面板有一个丑陋的灰色顶部

    我有一个 Flex 4 Spark 面板 我通过 PopUpManager 弹出 但它的顶部有一个我无法摆脱的灰色部分 那是什么以及如何删除它 UPDATE 下面是一个示例面板 我只是简单地打电话PopUpManager addPopUp
  • C 中 scanf 中的扫描集行为

    我尝试用 scanf 中的 scanset 做一些事情 但卡在某个地方 当我写的时候 char s1 250 scanf A Z s1 input AHJHkiuy Output AHJH 有了这个 scanf n s1 input abc
  • Joi 验证显示自定义错误消息

    嗨我正在使用 hapi joi 15 1 1 不幸的是 我现在无法更新到最新的 Joi 版本 这是我的验证架构 const schema name Joi string allow max 30 addLine1 Joi string re
  • 使用 NSTask 创建 zip 存档,其中包含包含文件的第一级文件夹

    我的方法适用于从先前创建和填充的临时目录中压缩文件 NSURL destURL self archiveDestURL NSTask task NSTask alloc init task setCurrentDirectoryPath s
  • .NET/CLR 上的 Scala 中的具体化泛型

    Scala 至少在JVM https en wikipedia org wiki Java virtual machine uses 类型擦除 https stackoverflow com tags type erasure info以实
  • php 使用 strtotime 获取一年中第一周的正确日期

    我使用此代码来获取一年中第一周的第一个日期 echo date Y m d strtotime 2018W01 JAN 1 is Monday returned 01 01 echo date Y m d strtotime 2013W01
  • 如何在 nextJS getserversideprops 中使用 firebase

    如果有签名用户 我想使用 getServerSideProps 在 Firestore 中获取 示例 文档 下面的代码不起作用 结果是 无法读取 我应该怎么办 或者还有其他方法吗 export const getServerSideProp
  • 虚函数的实现可以放在头文件中吗

    通常 如果我们将非虚拟成员函数的实现放入头文件中 该函数将被内联 如果我们将虚拟成员函数的实现放在头文件中怎么样 我想这与将其放入 cpp 文件中是一样的 因为内联和多态性不能一起工作 我的说法正确吗 将方法的实现放入头文件中并不会使其内联
  • 杜伦达尔 谷歌翻译

    如何在 Durundal Shell js shell html 中绑定 Google 翻译 html div div script function googleTranslateElementInit new google transl
  • Web 套接字与间隔轮询

    我目前正在寻找最合适的解决方案来处理通知 我当前的选择是使用 websockets 或仅进行轮询 每分钟仅 1 个请求 无长轮询 无永久轮询 我在寻找这些方法的性能指标时遇到了一些问题 结果应该能够并行处理大量用户 而不占用太多资源 选项A
  • SwiftUI CoreData 崩溃预览

    我有以下代码来绘制汽车列表 数据存储在 coredata 中 然而 当我添加从数据库获取数据的代码行时 swiftui 预览似乎中断了 错误日志显示以下内容 PotentialCrashError 测试 app app 可能已崩溃 里程应用
  • ActionBarSherlock 和 FragmentTabsPager

    正如很多人到目前为止所做的那样 我正在将 FragmentTabsPager 实现到我的应用程序中 该应用程序使用 ActionBarSherlock 4 0 然而 我迷路了 碎片 以及谷歌围绕它的所有小想法 计划和方法 都让我感到困惑 如
  • 将 JSON 转换为 C# 类型

    我想像这样使用 JS 中的未知对象 aa abcd 1 uio uio2 uio3 opee1 opee2 opee3 abcd 2 null abcd 3 null abcd 4 null 发送到 MVC 内容类型为 applicatio
  • 显示将用户带到该网站的 Google 关键字

    我希望显示类似的内容 您好 您是通过搜索 google 关键字 到达此网站的 我很确定我以前见过这样做 但我在弄清楚如何获取用于引导用户访问我的网站的关键字时遇到了麻烦 有人知道答案吗 您需要获取引用 URL 然后删除 q 查询字符串的所有
  • jquery 焦点无法在加载 ajax 的页面上工作

    My code 索引 php
  • 是什么导致 Visual Studio 无法正确加载程序集?

    我一直很高兴地编写一个规模相当大的解决方案 刚刚超过 13k LOC 5 个项目 该解决方案利用 Linq to Sql 进行数据访问 突然间 我执行了正常的构建 并收到了一条甜蜜的 甜蜜的模糊消息 错误 1 由于 C xxx xxx db
  • 如何在 Vim 中找出某个快捷键触发了哪个命令

    I try to execute a command in some plugin by pushing it s keyboard shortcut F2 But some other command is executed instea
  • RequireJS 和 Webapp Yo 生成器上出现“define”未定义错误

    我花了几天的时间来解决这个问题 但今天我终于需要你的帮助 我的仓库 https github com seoyoochan bitsnut web https github com seoyoochan bitsnut web 我想要实现什
  • 如何通过互操作公开 COM 库中定义的枚举作为 C# 函数的返回类型

    希望问题很清楚 但为了清楚起见 请补充一下 我有一个 VB6 dll 它定义了我在 C dll 中引用的枚举 C dll 使用 idispatch 接口以正确的方式定义 CCW 该接口声明返回类型为枚举的函数 运行 regasm 时 我收到