如何将字节数组作为 UDT 属性从 VB6/VBA 传递到 C# COM DLL?

2024-04-15

我有一个 C# 库,我试图将其公开给 VBA。我可以很好地将参数传递给函数(即“ref byte[] someArray”),但传递对象或结构是行不通的。

如果我尝试将字节数组作为类的属性传递,我会在 VB 中收到以下错误:

函数或接口标记为受限,或者函数使用 Visual Basic 不支持的自动化类型

如果我尝试将字节数组作为结构体的属性传递,我会在 VB 中收到以下错误:

我已经为此奋斗了两天,虽然我不断寻找声称有答案的帖子,但没有一个对我有用。

这是我当前的代码:

[ComVisible(true)]
[Guid("7F53F7A5-15C9-4A99-A855-38F5E87702D0")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]       // Tried as InterfaceIsDual and as InterfaceIsIDispatch
public interface IDetail
{
    [DispId(1)]     // Tried with and without these
    int SomeInt { get; set; }

    [DispId(2)]
    string SomeString { get; set; }

    [DispId(3)]
    byte[] SomeByteArray { 
        return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
        get;
        [param: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
        set; 
    }
}

[ComVisible(true)]
[Guid("F77FB3D4-27E0-4BFA-A21E-5ACB671151E9")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("G4COMTest.Detail")]
public class Detail:IDetail
{
    public int SomeInt { get;set; }
    public string SomeString { get; set; }

    // Tried MarshalAs in all combinations of class and interface
    public byte[] SomeByteArray {
        [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
        get; 
        [param: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
        set;
    }
}

[ComVisible(true)]
[Guid("5E8F9FF0-3156-479E-A91D-0DADD43881FB")]
[ClassInterface(ClassInterfaceType.None)]
public class Worker:IWorker
{
    // works with the 'ref'
    public int ReturnIntWByteArrayParam(ref byte[] testByteArray)
    {
        return testByteArray.Count();
    }

    public int ReturnIntWObjParam(IDetail detail)
    {
        return detail.SomeInt;
    }

    public IDetail ReturnObjNoParams()
    {
        var o = new Detail();
        o.SomeInt = 87;
        o.SomeString = "What are you doing Dave";
        return o;
    }
}

[ComVisible(true)]
[Guid("04962F29-DBBD-48AC-B4FB-180EEF562771")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IWorker
{
    int ReturnIntWByteArrayParam(ref byte[] testByteArray);
    int ReturnIntWObjParam(IDetail detail);
    IDetail ReturnObjNoParams();
}

从 VB6 调用它:

Dim o As New G4COMTest.Worker
Dim d As New G4COMTest.Detail
Dim byt(2) As Byte

d.SomeInt = 356                     '// Works
d.SomeString = "Hello from client"  '// Works
d.SomeByteArray = byt               '// Errors as either class or struct
MsgBox mWorker.ReturnIntWObjParam(d)

预先感谢您的任何帮助!


C# 数组属性向 COM 公开一个 getter 和一个 setter,正如您所期望的那样(MarshalAs属性是不必要的,封送拆收器默认情况下会正确检测到它)。

问题在于,与 .NET 中的所有属性设置器一样,设置器也是按值传递值参数。不幸的是,VBA 不支持按值传递数组。这是从一开始就存在的语言的基本限制。更不幸的是,COM 互操作不提供任何使用属性覆盖此行为的方法。你有两个选择:

A - 定义您自己的 setter 方法并从 VBA 调用它而不是属性 setter,例如

void SetSomeByteArray(ref byte[] value) { SomeByteArray = value; }

B - 将属性类型更改为object并使用变体数组而不是强类型数组。

PS:要小心string属性也。这些通常工作得很好,但是如果你通过了null字符串值到VBA,会出错,因为VBAString类型无法存储null参考。

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

如何将字节数组作为 UDT 属性从 VB6/VBA 传递到 C# COM DLL? 的相关文章

  • QCombobox 向下箭头图像

    如何更改Qcombobox向下箭头图像 现在我正在使用这个 QSS 代码 但这不起作用 我无法删除向下箭头边框 QComboBox border 0px QComboBox down arrow border 0px background
  • FileStream 构造函数和默认缓冲区大小

    我们有一个使用 NET 4 用 C 编写的日志记录类 我想添加一个构造函数参数 该参数可以选择设置文件选项 WriteThrough http msdn microsoft com en us library system io fileo
  • 使用 Enumerable.OfType() 或 LINQ 查找特定类型的所有子控件

    Existed MyControl1 Controls OfType
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 如何在 C# 控制台应用程序中将修饰符(ctrl、alt、shift)按键捕获为单个按键?

    Console ReadKey 仅在按下 正常 键时捕获输入 然后将修饰符 如果有 附加为键信息的一部分 如何将单个修饰键注册为输入 提供了一种解决方案这个链接 https blogs msdn microsoft com toub 200
  • 时间:2019-03-17 标签:c#ThreadSafeDeepCopy

    我一直在阅读很多其他问题以及大量谷歌搜索 但我一直无法找到明确的解决方案 根据我读过的一些最佳实践 类的静态方法应该创建线程安全的 并且实例成员应该将线程安全留给消费者 我想为该类实现深度复制方法 该类本身还有其他引用类型成员 有没有什么方
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • Visual Studio Code:如何配置 includePath 以获得更好的 IntelliSense 结果

    我是使用 Visual Studio Code 的完全初学者 我不知道我在做什么 我已经四处搜索 也许还不够 但我找不到像我这样的人如何配置的简单解释c cpp properties json每当我单击带有绿色波浪线下划线的行旁边的黄色灯泡
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • 字典、集合和数组的比较

    我正在尝试找出字典与集合和数组相比的相对优点和功能 我发现了一篇很棒的文章here http www experts exchange com articles 3391 Using the Dictionary Class in VBA
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 在 EnvDTE 中调试时捕获 VS 局部变量

    是否可以使用 EnvDTE 进行 vsix Visual Studio 扩展来捕获本地和调试窗口使用的调试数据 或者可以通过其他方法吗 我想创建一个自定义的本地窗口 我们可以修改它以根据需要显示一些较重的内容 而无需为高级用户牺牲原始的本地
  • 使用restsharp序列化对象并将其传递给WebApi而不是序列化列表

    我有一个看起来像的视图模型 public class StoreItemViewModel public Guid ItemId get set public List
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 每个数据库多个/单个 *.edmx 文件

    我有一个通过 ADO net 数据服务与数据库交互的项目 数据库很大 近 150 个具有依赖关系的表 该项目几年前开始 当时使用的是数据集 现在我们正在转向实体模型关系 由于我们添加了更多需要使用的表 该模型正在不断增长 这是管理这一切的正
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo

随机推荐

  • 如何在windows上安装uwsgi?

    我正在尝试在虚拟环境中为 django 项目安装 uwsgi 我使用的是 Windows 10 I did pip install uwsgi我得到了Command python setup py egg info 所以为了解决这个错误 我
  • 收集装置不会注入

    我正在使用 xUnit 2 0收集装置 http xunit github io docs shared context html在许多不同的测试类之间共享公共数据库设置 拆卸 该装置还提供了一些辅助属性 因此我将其注入到每个测试类中 我在
  • 无法将上游映射到 nginx 服务器中的文件夹

    我想将系统端口 82 映射到 127 0 0 1 8080 runningSite 但 nginx 配置出现异常 upstream dev server 127 0 0 1 8080 runningSite server rewrite l
  • ruby 1.9 和 RSpec2 有什么好的突变测试工具吗?

    我曾经使用 Heckle 但由于 ParseTree 的问题 它与 ruby 1 9 不兼容 我一直在寻找替代方案 但唯一看起来有希望的是 Chaser 而且它没有任何明确的文档可供我用来查看是否可以使其与 RSpec 一起使用 它似乎具有
  • 在构造函数中声明属性 Angular 2

    我是一名刚接触 Angular 2 的 java 程序员 在做官方教程时 我很惊讶地发现他们在构造函数中而不是在类的顶部声明了这个属性 我知道 Java 和 JS 有很大不同 但是这样做之间有什么技术原因吗 constructor priv
  • 将图像添加到 R 中的类似表格的输出

    我有一个简单的数据结构 案例是国家 地区 对于每个国家 地区我有几个数字变量 就像这样 dat lt data frame country c Belgium Germany Holland Ireland Var1 1 4 Var2 11
  • 使用 jQuery Validate 插件,如何将错误消息字符串包装在跨度中

    有谁知道如何将内部错误字符串包装在跨度中 我正在为我的表单使用 jQuery Validate 插件 并在标签标记中显示默认的错误消息 这目前还不错 例子
  • 设计 config.timeout_in 不起作用

    我无法使用初始化器 devise rb 中的设计会话超时来使会话超时 I set config timeout in 1 minute 在initializers devise rb 中 我使用一名用户登录并闲置了2 分钟 这假设会使当前会
  • 如何检查当前应用程序进程是否在 Laravel 的队列环境中运行

    我通过特征将全局作用域应用于我的模型 但我不希望在从 Redis 队列调用 处理模型时应用全局作用域 如何检测当前实例是否是队列进程 就像我们有这个 if App environment local The environment is l
  • Android Studio - 无法找到请求目标的有效认证路径

    我收到这个错误 Gradle project name project refresh failed Unable to find valid certification path to requested target 当我在 Andro
  • Where().Count() 和 Count() 之间的区别

    using DBEntities db new DBEntities var employeeAgedAbove30 db Employees Where s gt s Age gt 30 Count Method 1 employeeAg
  • 使用 Sequelize 的多对多关系的简单示例

    我正在尝试使用 Sequelize 构建表之间多对多关系的简单示例 然而 这似乎比我预期的要棘手得多 这是我目前拥有的代码 db js文件导出 Sequelize 连接实例 const Sequelize require sequelize
  • 计算圆形数量级

    对于一个简单的项目 我必须使大数字 例如 4294967123 可读 因此我只写带有前缀的前几个数字 4294967123 gt 4 29G 12345 gt 12 34K 等 代码 简化 如下所示 const char postfixes
  • 从 Cydia 安装调整后重新启动

    我使用 DHowett 的 Theos 对应用程序和 mobilesubstrate 进行了调整 Tweak是应用程序的一个子项目 我在 iPhone 上测试过 一切正常 然后我创建了一个 Cydia 存储库并将我的项目加载到其中 问题是当
  • 未捕获的语法错误:意外的令牌导出

    我用过创建反应应用程序对于我的项目 我收到一个错误 未捕获的语法错误 意外的令牌导出 错误就在这段代码中 export const ENGLISH lang en messages nav translatedMessage Social
  • 使用 Apache Maths 进行多项式回归 (Java)

    有人可以帮我用 Apache Math 库进行多项式回归 2 阶 吗 以下数据应给出此方程 39 79 x 2 497 66 x 997 45 由 Excel 计算 r2 0 9998 coding style from http comm
  • 无法通过 AKS 上的 Azure 流量管理器和 Nginx Ingress 访问服务

    我在两个不同的区域有两个 AKS 集群作为主要集群和辅助集群 我想使用 Azure 流量管理器在主集群和辅助集群上进行基于优先级的端点监控和故障转移机制 我有两个服务 A 和 B 它们在相对路径上路由 服务 a and 服务 b分别 我在每
  • 如何在 python 3 及更高版本中永久删除文件?

    我想永久删除我用 python 代码创建的文件 我知道 os remove 等 但找不到任何特定的内容来永久删除文件 不想用未使用的文件填充垃圾箱 os remove已经是您正在寻找的了 它不会将东西发送到垃圾箱 它只是删除它们
  • 苹果商店拒绝iPhone申请的原因[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 谁能帮我了解苹果商店拒绝或提出反对提交任何iPhone申请的可能原因 以下是可能的原因 非官方的 从这里 http 10base t co
  • 如何将字节数组作为 UDT 属性从 VB6/VBA 传递到 C# COM DLL?

    我有一个 C 库 我试图将其公开给 VBA 我可以很好地将参数传递给函数 即 ref byte someArray 但传递对象或结构是行不通的 如果我尝试将字节数组作为类的属性传递 我会在 VB 中收到以下错误 函数或接口标记为受限 或者函